线段树FB

hdu 1166 敌兵布阵

最简单的单点更新,因为是第一题线段树,学习了网上的题解之后写的

 1 #include
 2 #include
 3 using namespace std;
 4 
 5 const int maxn = 50000;
 6 
 7 struct segment{
 8      int l,r,sum;
 9 } T[maxn*4];
10 
11 void build(int l,int r,int k)
12 {
13     T[k].l = l;
14     T[k].r = r;
15     T[k].sum = 0;
16     if(l == r) return;
17     int mid = (l + r) >> 1;
18     build(l, mid, 2*k);
19     build(mid+1, r, 2*k+1);
20 }
21 
22 //查询
23 int ans;
24 void query(int k, int l, int r)
25 {
26     if(T[k].l == l && T[k].r == r)
27     {
28         ans += T[k].sum;
29         return ;
30     }
31     int mid = (T[k].l + T[k].r) >> 1;
32     if(r<=mid)       query(2*k,l,r);
33     else if(l>mid)   query(2*k+1,l,r);
34     else
35     {
36         query(2*k,l,mid);
37         query(2*k+1,mid+1,r);
38     }
39     return ;
40 }
41 
42 void update(int k, int d,int n)
43 {
44     if(T[k].l == T[k].r && T[k].l == d)
45     {
46         T[k].sum += n;      // 叶节点, 更新sum
47         return ;
48     }
49     int mid = (T[k].l + T[k].r) >> 1;
50     if(d <= mid) update(k*2, d, n); else update(k*2+1, d, n);
51        //更新本结点的sum
52     T[k].sum = T[k*2].sum + T[k*2+1].sum;
53 }
54 
55 
56 
57 int main()
58 {
59     int t, Case = 0;
60     scanf("%d",&t);
61     while(t--)
62     {
63         int n,x;
64         scanf("%d",&n);
65         build(1,n,1);
66         for(int i = 1; i <= n; i++)
67         {
68             scanf("%d",&x);
69             update(1,i,x);
70         }
71         printf("Case %d:\n",++Case);
72         char str[11];
73         while(~scanf("%s",str) && str[0] != 'E')
74         {
75             int a,b;
76             scanf("%d%d",&a,&b);
77             if(str[0] == 'Q')
78             {
79                  ans = 0;
80                  query(1,a,b);
81                  printf("%d\n",ans);
82             }
83             if(str[0] == 'A')
84                  update(1,a,b);
85             if(str[0] == 'S')
86                  update(1,a,-b);
87         }
88     }
89     return 0;
90 }

 

你可能感兴趣的:(线段树FB)