首页 > 其他 > 详细

线段树的学习过程

时间:2015-02-09 00:30:33      阅读:355      评论:0      收藏:0      [点我收藏+]

敌兵布阵。

技术分享
  1 #include<stdio.h>
  2 #include<string.h>
  3 #define lson l,mid,res<<1
  4 #define rson mid+1,r,res<<1|1
  5 //感谢图灵;
  6 int tree[50000*4];
  7 //res是树对应数组位置。
  8 void PushUp(int res)
  9 {
 10     tree[res] = tree[res<<1]+tree[res<<1|1];
 11 }
 12 void build(int l,int r,int res)
 13 {
 14     if(l==r)
 15     {
 16         scanf("%d",&tree[res]);
 17         return;
 18     }
 19     int mid = (l+r)>>1;
 20     build(lson);
 21     build(rson);
 22     PushUp(res);
 23 }
 24 //goal军营目标
 25 void Add(int l,int r,int res,int goal,int ad)
 26 {
 27     if(l==r)
 28     {
 29         tree[res] += ad;
 30         return;
 31     }
 32     int mid  = (l+r)>>1;
 33     if(goal<=mid)
 34     {
 35         Add(l,mid,res<<1,goal,ad);
 36     }
 37     else
 38     {
 39         Add(mid+1,r,res<<1|1,goal,ad);
 40     }
 41     PushUp(res);
 42 }
 43 void Del(int l,int r,int res,int goal,int ad)
 44 {
 45     if(l==r)
 46     {
 47         tree[res] -= ad; 
 48         return;
 49     }
 50     int mid  = (l+r)>>1;
 51     if(goal<=mid)
 52     {
 53         Del(l,mid,res<<1,goal,ad);
 54     }
 55     else
 56     {
 57         Del(mid+1,r,res<<1|1,goal,ad);
 58     }
 59     PushUp(res);
 60 }
 61 
 62 int Query(int l,int r,int res,int ll,int rr)
 63 {
 64     if(l>=ll&&r<=rr)
 65     {
 66         return tree[res];
 67     }
 68     int mid = (l+r)>>1;
 69     if(rr<=mid)
 70     {
 71         return Query(l,mid,res<<1,ll,rr);
 72     }
 73     else if(ll>mid)
 74     {
 75         return Query(mid+1,r,res<<1|1,ll,rr);
 76     }
 77     else
 78     {
 79         return (Query(l,mid,res<<1,ll,rr)+Query(mid+1,r,res<<1|1,ll,rr));
 80     }
 81     /*
 82         存在rr>r的情况。 比如 2 7 。 r = mid = 5 
 83         所以我的判断是 l>=ll r<=rr 
 84         notonlysuccess 的代码
 85         int query(int L,int R,int l,int r,int rt) {
 86         if (L <= l && r <= R) {
 87         return sum[rt];
 88         }
 89         int m = (l + r) >> 1;
 90         int ret = 0;
 91         if (L <= m) ret += query(L , R , lson);
 92         if (R > m) ret += query(L , R , rson);
 93         return ret;
 94         }
 95         利用的是分开讨论。L和R 而不是统一讨论区间L~R(这个思维不错。)
 96     */
 97 }
 98 
 99 int main()
100 {
101     int T,N,M,i,j;
102     char command[10];
103     scanf("%d",&T);
104     M = T;
105     while(T--)
106     {
107         scanf("%d",&N);
108         build(1,N,1);
109         printf("Case %d:\n",M-T);
110         while(scanf("%s",command)!=EOF)
111         {
112             if(!strcmp(command,"End"))
113             {
114                 break;
115             }
116             else if(command[0]==A)
117             {
118                 scanf("%d%d",&i,&j);
119                 Add(1,N,1,i,j);
120             }
121             else if(command[0]==Q)
122             {
123                 scanf("%d%d",&i,&j);
124                 printf("%d\n",Query(1,N,1,i,j));
125             }
126             else
127             {
128                 scanf("%d%d",&i,&j);
129                 Del(1,N,1,i,j);
130             }
131         }
132     }
133 }
134 //注意res的含义。还有函数的参数比我想象中要多
View Code

 

线段树的学习过程

原文:http://www.cnblogs.com/Milkor/p/4280691.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!