[HDU 1166]敌兵布阵

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HDU 1166]敌兵布阵相关的知识,希望对你有一定的参考价值。

zkw线段树,是zkw大佬发明的一种非递归线段树.

(然而zzs大佬说只是优化常数罢了)

技术分享

zkw线段树中,一个节点的父亲是\\(\\left( {\\frac{x}{2}} \\right)\\),儿子是\\(2x\\)和\\(2x + 1\\).利用这个性质可以优化常数(然而似乎还是慢的要死)

 

题目大意:

一个序列里有n个数.每次单点修改,区间求和.

 

代码如下:

 1 #include <cstdio>
 2 #include <cstring>
 3 const int N = 50005;
 4 int T[N * 4];
 5 int M = 1;
 6 char command[6];
 7 void build(int n)
 8 {
 9     for(;M <= n + 1;M <<= 1);
10     for(int i = M + 1;i <= M + n;i++) scanf("%d",&T[i]);
11     for(int i = M - 1;i > 0;i--) T[i] = T[i + i] + T[i + i + 1];
12 }
13 int query(int i,int j)
14 {
15     int ans = 0;
16     for(i = i + M - 1,j = j + M + 1;i ^ j ^ 1;i >>= 1,j >>= 1)
17     {
18         if(~i&1) ans += T[i^1];
19         if(j&1) ans += T[j^1];
20     }
21     return ans;
22 }
23 void add(int i,int j){for(T[i += M] += j,i >>= 1;i;i >>= 1) T[i] = T[i + i] + T[i + i + 1];}
24 void sub(int i,int j){for(T[i += M] -= j,i >>= 1;i;i >>= 1) T[i] = T[i + i] + T[i + i + 1];}
25 int main()
26 {
27     int t;scanf("%d",&t);int k = 0;
28     while(t--)
29     {
30         printf("Case %d:\\n",++k);
31         int n;scanf("%d",&n);
32         memset(T,0,sizeof(T));
33         build(n);
34         while(1)
35         {
36             scanf("%s",command);int i,j;
37             if(!strcmp(command,"Query"))
38             {
39                 scanf("%d %d",&i,&j);
40                 printf("%d\\n",query(i,j));
41             }
42             else if(!strcmp(command,"Add")){scanf("%d %d",&i,&j);add(i,j);}
43             else if(!strcmp(command,"Sub")){scanf("%d %d",&i,&j);sub(i,j);}
44             else break;
45         }
46     }
47     return 0;
48 }

 

以上是关于[HDU 1166]敌兵布阵的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1166 敌兵布阵

[HDU 1166]敌兵布阵

hdu 1166 敌兵布阵

HDU 1166 敌兵布阵

HDU 1166 敌兵布阵(线段树)

HDU 1166 敌兵布阵 (树状数组)