HDU 1166 敌兵布阵(第一个线段树)
这个题,用完树状数组,再用线段树水过。线段树,却是感觉比树状数组的功能强多了。只要把线段树的思想理解,然后把实现过程,递归过程了解,单点更新就没问题了。
#include <stdio.h> #include <string.h> #include <stdlib.h> #define N 50001 struct node { int l; int r; int v; }tree[4*N]; void build(int l,int r,int rt) { int m; tree[rt].l = l; tree[rt].r = r; if(l == r) { scanf("%d",&tree[rt].v); return; } m = (l+r)>>1; build(l,m,rt<<1); build(m+1,r,rt<<1|1); tree[rt].v = tree[rt<<1].v + tree[rt<<1|1].v; } void update(int pos,int sc,int rt) { int m; if(tree[rt].l == tree[rt].r) { tree[rt].v += sc; return ; } m = (tree[rt].l + tree[rt].r) >> 1; if(pos <= m) update(pos,sc,rt<<1); else update(pos,sc,rt<<1|1); tree[rt].v = tree[rt<<1].v + tree[rt<<1|1].v; } int query(int L,int R,int rt) { int m; if(tree[rt].l == L&&tree[rt].r == R) { return tree[rt].v; } m = (tree[rt].l + tree[rt].r) >> 1; if(L > m) { return query(L,R,rt<<1|1); } else if(R <= m) { return query(L,R,rt<<1); } else { return query(L,m,rt<<1)+query(m+1,R,rt<<1|1); } } int main() { int t,num = 0,x,y,n; char str[100]; scanf("%d",&t); while(t--) { num ++; memset(tree,0,sizeof(tree)); scanf("%d",&n); build(1,n,1); scanf("%s",str); printf("Case %d:\n",num); while(strcmp(str,"End") != 0) { scanf("%d%d%*c",&x,&y); if(strcmp(str,"Query") == 0) printf("%d\n",query(x,y,1)); else if(strcmp(str,"Add") == 0) update(x,y,1); else if(strcmp(str,"Sub") == 0) update(x,-y,1); scanf("%s",str); } } return 0; }