这两题我都在之前做过,但并未通过,那次做的时候是刚开始接触线段树,现在有了一点点的了解,翻出以前的代码稍作修改就AC了。之前1698错误的原因是没有注意到位运算的优先级。
//hdoj 1698 #include<stdio.h> #include<string.h> #define maxn 100010 struct node { int l; int r; int mid; int val; }tree[maxn<<2]; void buildtree(int o,int l,int r) { tree[o].val = 1; tree[o].l = l; tree[o].r = r; tree[o].mid = (l + r)>>1; if(l == r) return ; else { buildtree(o<<1, l, tree[o].mid); buildtree((o<<1)+1, tree[o].mid + 1, r); } } void update(int o, int l, int r, int val) { if(l == tree[o].l && r == tree[o].r) { tree[o].val = val; return ; } //递归边界,如果更新的边界和节点边界相同则返回 if(tree[o].val != 0) { tree[o<<1].val = tree[o].val; tree[(o<<1)+1].val = tree[o].val; tree[o].val = 0; } //这个地方是为了表示tree[o]的两个节点的val值是不一样的 //要更新的段无非三种情况,要么在l-mid段,要么在mid-r段,再么就是两端都存在的,分情况递归 if(r <= tree[o].mid) update(o<<1, l, r, val); //这个是位于l-mid段的 else if(l > tree[o].mid) update((o<<1)+1, l, r, val); //这个是位于mid-r段的 else { update(o<<1, l, tree[o].mid, val); update((o<<1)+1, tree[o].mid + 1, r, val); } //两段都有的情况 } int getsum(int o,int l,int r) { if(tree[o].val > 0) return tree[o].val * (tree[o].r - tree[o].l + 1); //tree[o].val > 0 证明在tree[o].l到tree[o].r区间里面的val都是一样的,要获取的区间也属于该区间 if(r <= tree[o].mid) return getsum(o * 2, l, r); //同 update() 也是分三种情况 else if (l > tree[o].mid) return getsum((o<<1)+1, l, r); else return getsum(o<<1, l, tree[o].mid) + getsum((o<<1)+1, tree[o].mid, r); } int main() { int t, n, i, j, op, x, y, z; scanf("%d",&t); for(i = 1;i <= t;i++) { scanf("%d",&n); buildtree(1, 1, n); scanf("%d",&op); while(op--) { scanf("%d%d%d",&x,&y,&z); update(1, x, y, z); } int ans = getsum(1,1,n); printf("Case %d: The total value of the hook is %d.\n",i,ans); } return 0; }
//hdoj 1754 #include<stdio.h> #include<string.h> #define maxn 200005 struct node { int l; int r; int mid; int max; }tree[maxn<<2]; int arr[maxn]; int max(int a,int b) { return a > b ? a : b; } void build(int o, int l, int r) { tree[o].l = l; tree[o].r = r; tree[o].mid = (l + r)>>1; if(l == r) { tree[o].max = arr[l]; return ; } build(o<<1, l, tree[o].mid); build((o<<1)+1, tree[o].mid + 1, r); tree[o].max = max(tree[o<<1].max, tree[(o<<1)+1].max); } void update(int o, int l, int r,int a, int val) { tree[o].max = max(tree[o].max, val); if(tree[o].l == tree[o].r) { return ; } if(a <= tree[o].mid) update(o<<1,l,tree[o].mid,a,val); else update((o<<1)+1, tree[o].mid + 1, r, a, val); } int query(int o,int l,int r) { if(l == tree[o].l && r == tree[o].r) return tree[o].max; if(r <= tree[o].mid) return query(o*2,l,r); if(l > tree[o].mid) return query((o<<1)+1, l, r); return max(query(o<<1, l, tree[o].mid),query((o<<1)+1, tree[o].mid+1, r)); } int main() { int n, m, i, t, a, b; char c; while(scanf("%d%d",&n,&m) != EOF) { for(i = 1;i <= n;i++) { scanf("%d",&arr[i]); } build(1,1,n); while(m--) { getchar(); scanf("%c%d%d",&c,&a,&b); if(c == 'U') update(1,1,n,a,b); else printf("%d\n",query(1,a,b)); } } return 0; }