[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]敌兵布阵的主要内容,如果未能解决你的问题,请参考以下文章