码迷,mamicode.com
首页 > 其他好文 > 详细

[HDU 1166]敌兵布阵

时间:2017-09-28 10:04:55      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:memset   优化   bsp   http   个性   for   eof   log   return   

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]敌兵布阵

标签:memset   优化   bsp   http   个性   for   eof   log   return   

原文地址:http://www.cnblogs.com/gcc314/p/7604807.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!