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

线段树模板

时间:2018-08-21 22:34:08      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:tps   模板   http   pre   线段树   www   include   .com   printf   

参考:http://www.cnblogs.com/TheRoadToTheGold/p/6254255.html

语法参考:https://blog.csdn.net/dimensionoffive/article/details/70054356

https://www.cnblogs.com/fnlingnzb-learner/p/6423917.html

  1 #include<cstdio>
  2 using namespace std;
  3 int n,p,m,ans;
  4 struct node
  5 {
  6     int l,r,w,f;//l区间左端点,l区间右端点,w区间和,f懒惰标记
  7 }tree[400001];
  8 inline void build(int k,int ll,int rr)//建树,k节点序号,ll区间左端点,rr区间右端点
  9 {
 10     tree[k].l=ll,tree[k].r=rr;
 11     if(tree[k].l==tree[k].r)
 12     {
 13         scanf("%d",&tree[k].w);
 14         return;
 15     }
 16     int m=(ll+rr)/2;
 17     build(k*2,ll,m);
 18     build(k*2+1,m+1,rr);
 19     tree[k].w=tree[k*2].w+tree[k*2+1].w;
 20 }
 21 inline void down(int k)//标记下传,k节点序号
 22 {
 23     tree[k*2].f+=tree[k].f;
 24     tree[k*2+1].f+=tree[k].f;
 25     tree[k*2].w+=tree[k].f*(tree[k*2].r-tree[k*2].l+1);
 26     tree[k*2+1].w+=tree[k].f*(tree[k*2+1].r-tree[k*2+1].l+1);
 27     tree[k].f=0;
 28 }
 29 inline void ask_point(int x,int k)//单点查询,x要查询点
 30 {
 31     if(tree[k].l==tree[k].r)
 32     {
 33         ans=tree[k].w;
 34         return ;
 35     }
 36     if(tree[k].f) down(k);
 37     int m=(tree[k].l+tree[k].r)/2;
 38     if(x<=m) ask_point(x,k*2);
 39     else ask_point(x,k*2+1);
 40 }
 41 inline void change_point(int x,int y,int k)//单点修改,x要修改点,y要添加值
 42 {
 43     if(tree[k].l==tree[k].r)
 44     {
 45         tree[k].w+=y;
 46         return;
 47     }
 48     if(tree[k].f) down(k);
 49     int m=(tree[k].l+tree[k].r)/2;
 50     if(x<=m) change_point(x,y,k*2);
 51     else change_point(x,y,k*2+1);
 52     tree[k].w=tree[k*2].w+tree[k*2+1].w;
 53 }
 54 inline void ask_interval(int x,int y,int k)//区间查询,x查询区间左端,y查询区间右端
 55 {
 56     if(tree[k].l>=x&&tree[k].r<=y)
 57     {
 58         ans+=tree[k].w;
 59         return;
 60     }
 61     if(tree[k].f) down(k);
 62     int m=(tree[k].l+tree[k].r)/2;
 63     if(x<=m) ask_interval(x,y,k*2);
 64     if(y>m) ask_interval(x,y,k*2+1);
 65 }
 66 inline void change_interval(int x,int y,int num,int k)//区间修改,x区间左端,y区间右端,num要添加值
 67 {
 68     if(tree[k].l>=x&&tree[k].r<=y)
 69     {
 70         tree[k].w+=(tree[k].r-tree[k].l+1)*num;
 71         tree[k].f+=num;
 72         return;
 73     }
 74     if(tree[k].f) down(k);
 75     int m=(tree[k].l+tree[k].r)/2;
 76     if(x<=m) change_interval(x,y,num,k*2);
 77     if(y>m) change_interval(x,y,num,k*2+1);
 78     tree[k].w=tree[k*2].w+tree[k*2+1].w;
 79 }
 80 int main()
 81 {
 82     freopen("in.txt","r",stdin);
 83     scanf("%d",&n);//n个节点
 84     build(1,1,n);//建树
 85     scanf("%d",&m);//m种操作,在线段树题中不要用cin,cout!
 86     for(int i=1;i<=m;i++)
 87     {
 88         scanf("%d",&p);
 89         ans=0;//ans为全局变量
 90         int x,y,a,b;
 91         if(p==1)
 92         {
 93             scanf("%d",&x);
 94             ask_point(x,1);//单点查询,输出第x个数
 95             printf("%d\n",ans);
 96         }
 97         else if(p==2)
 98         {
 99             scanf("%d%d",&x,&y);
100             change_point(x,y,1);//单点修改
101         }
102         else if(p==3)
103         {
104             scanf("%d%d",&a,&b);//区间查询
105             ask_interval(a,b,1);
106             printf("%d\n",ans);
107         }
108         else
109         {
110              scanf("%d%d%d",&a,&b,&y);//区间修改
111              change_interval(a,b,y,1);
112         }
113     }
114 }
115 /*输入
116 10
117 1 2 3 4 5 6 7 8 9 10
118 10
119 1 1
120 1 10
121 2 1 11
122 2 10 11
123 3 1 10
124 3 10 10
125 4 1 10 2
126 4 1 1 2
127 1 6
128 3 5 5
129 */
130 
131 /*输出
132 1
133 10
134 77
135 21
136 8
137 7
138 */

 

线段树模板

标签:tps   模板   http   pre   线段树   www   include   .com   printf   

原文地址:https://www.cnblogs.com/hemeiwolong/p/9514518.html

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