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

线段树

时间:2014-08-07 00:45:07      阅读:205      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   数据   for   

线段树是一个碉炸的数据结构,有多碉炸呢?可以看一下zkw大神的《统计的力量》,里面是讲zkw树的,不用看懂,就了解一下线段树有多碉炸就行。

 看我把它撸过来:

 

然后我们来学一下线段树。

线段树一般是怒存在数组里的,一般a[1]是根节点,然后a[i]的左儿子是a[i<<1] (i<<1是位运算向左移1位,相当于乘2),右儿子是a[i<<1 | 1],爸是a[i>>1]。

根据这个规律,我们可以用递归来用线段树处理点、区间问题。

线段树一般有几个函数,build初始化线段树,update对线段树进行修改,query对线段树进行查询。然后里面用到PushUp和PushDown,分别是从当前节点的儿子收集信息传给当前节点、把当前节点的信息传下去给儿子,有时只用其中的一个,有时两个都用。

最简单的是单点修改、区间求和。修改的容易,自顶向下递归找到那个要改的点,改一发。区间求和要求单点修改的时候就计算好区间的和,回溯的时候PushUp传递上去。

我的代码都是参照http://www.notonlysuccess.com/index.php/segment-tree-complete/写的,比较好懂,推荐大家看他的碉代码。

例1.敌兵布阵

单点加减,区间求和。

bubuko.com,布布扣
 1 #include<cstdio>
 2 #include<cmath>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<cmath>
 7 #include<map>
 8 #include<set>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define ll __int64
13 #define usint unsigned int
14 #define mz(array) memset(array, 0, sizeof(array))
15 #define minf(array) memset(array, 0x3f, sizeof(array))
16 #define REP(i,n) for(int i=0;i<(n);i++)
17 #define FOR(i,x,n) for(int i=(x);i<=(n);i++)
18 #define RD(x) scanf("%d",&x)
19 #define RD2(x,y) scanf("%d%d",&x,&y)
20 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
21 #define WN(x) printf("%d\n",x);
22 #define RE  freopen("D.in","r",stdin)
23 #define WE  freopen("1.out","w",stdout)
24 
25 #define lson l,m,rt<<1
26 #define rson m+1,r,rt<<1|1
27 const int maxn=51111;
28 int a[maxn<<2];
29 
30 void PushUP(int rt){
31     a[rt]=a[rt<<1]+a[rt<<1|1];
32 }
33 
34 void build(int l,int r,int rt){
35     if(l==r){
36         scanf("%d",&a[rt]);
37         return;
38     }
39     int m=(l+r)>>1;
40     build(lson);
41     build(rson);
42     PushUP(rt);
43 }
44 
45 void update(int p,int add,int l,int r,int rt){
46     if(l==r){
47         a[rt]+=add;
48         return;
49     }
50     int m=(l+r)>>1;
51     if(p<=m)update(p,add,lson);
52     else update(p,add,rson);
53     PushUP(rt);
54 }
55 
56 int query(int L,int R,int l,int r,int rt){
57     if(L<=l&&r<=R){
58         return a[rt];
59     }
60     int m=(l+r)>>1;
61     int ret=0;
62     if(L<=m)ret+=query(L,R,lson);
63     if(R>m)ret+=query(L,R,rson);
64     return ret;
65 }
66 
67 int main()
68 {
69     int cas=1,T;
70     char s[10];
71     int x,y,i,n;
72     scanf("%d",&T);
73     while(T--)
74     {
75         scanf("%d",&n);
76         build(1,n,1);
77         printf("Case %d:\n",cas++);
78         while(scanf("%s",s)!=EOF){
79             if(s[0]==E)break;
80             scanf("%d%d",&x,&y);
81             if(s[0]==A) update(x,y,1,n,1);///x地增加y人
82             else if(s[0]==S)update(x,-y,1,n,1);///x地减少y人
83             else if(s[0]==Q)printf("%d\n",query(x,y,1,n,1));///x~y总人数
84         }
85     }
86     return 0;
87 }
View Code


例2.

 

(未完待续)

线段树,布布扣,bubuko.com

线段树

标签:style   blog   http   color   os   io   数据   for   

原文地址:http://www.cnblogs.com/yuiffy/p/3896085.html

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