线段树模板

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<iostream>
  5 #include<stdlib.h>
  6 #include<algorithm>
  7 #include<queue>
  8 #include<vector>
  9 #include<string>
 10 #include<set>
 11 #include<cctype>
 12 #include<sstream>
 13 #define mem(a) memset(a,0,sizeof(a))
 14 #define LL long long
 15 using namespace std;
 16 const int N=1e6+5;
 17 long long tree[4*N];//求和
 18 long long lazy[4*N];
 19 int a[N];//存原数组下标
 20 void push_up(int rt) //更新节点信息---求和
 21 {
 22     tree[rt]=tree[rt<<1]+tree[rt<<1|1];
 23 }
 24 void push_down(int rt,int len)
 25 {
 26   lazy[rt<<1]+=lazy[rt]; //当前节点的懒标记累积到子节点的懒标记中
 27   lazy[rt<<1|1]+=lazy[rt];
 28   tree[rt<<1]+=(len-(len>>1))*lazy[rt];//上下两条加起来就是len了,左儿子>=右二子
 29   tree[rt<<1|1]+=(len>>1)*lazy[rt];
 30   lazy[rt]=0;
 31 }
 32 void build(int rt,int l,int r) //rt为当前节点的实际存储位置
 33 {
 34     if(l==r)
 35     {
 36         //记录每个叶子结点的值
 37         tree[rt]=a[l];
 38         return;
 39     }
 40     int m=(l+r)>>1;
 41     build(rt<<1,l,m);
 42     build(rt<<1|1,m+1,r);
 43     push_up(rt);//更新信息
 44     return;
 45 }
 46 void update(int L,int x,int rt,int l,int r) //单点修改
 47 {
 48     if(l==r) {tree[rt]+=x;return;}
 49     int m=(l+r)>>1;
 50     if(L<=m)update(L,x,rt<<1,l,m);
 51     else update(L,x,rt<<1|1,m+1,r);
 52     push_up(rt);//子节点更新,原节点也要更新
 53 }
 54 void Update(int L,int R,int x,int rt,int l,int r) //区间修改
 55 {
 56     if(L<=l&&r<=R){
 57         tree[rt]+=(r-l+1)*x;
 58         lazy[rt]+=x;
 59         return;
 60     }
 61     if(lazy[rt]) push_down(rt,r-l+1); //?
 62     int m=(l+r)>>1;
 63     if(L<=m)Update(L,R,x,rt<<1,l,m);
 64     if(m<R) Update(L,R,x,rt<<1|1,m+1,r);
 65     push_up(rt);
 66 }
 67 long long qurey(int L,int R,int rt,int l,int r)//区间查询
 68 {
 69     if(L<=l&&r<=R)return tree[rt];
 70     int m=(l+r)>>1;
 71     long long ans=0;
 72      if(lazy[rt])push_down(rt,r-l+1);
 73     if(L<=m) ans+=qurey(L,R,rt<<1,l,m);
 74     if(R>m) ans+=qurey(L,R,rt<<1|1,m+1,r);
 75     return ans;
 76 }
 77 int main()
 78 {
 79    int n,m,L,R,x;
 80    char ty[5];
 81    scanf("%d %d",&n,&m);
 82    for(int i=1;i<=n;i++)
 83      scanf("%d",&a[i]);
 84    build(1,1,n); //建树
 85   // scanf("%d",&m);
 86    for(int i=1;i<=m;i++)
 87    {
 88        scanf("%s",ty);
 89        if(ty[0]=='C')
 90        {
 91            scanf("%d%d%d",&L,&R,&x);
 92            Update(L,R,x,1,1,n);
 93        }
 94        else if(ty[0]=='Q')
 95        {
 96           scanf("%d%d",&L,&R);
 97           printf("%I64d\n",qurey(L,R,1,1,n));
 98        }
 99    }
100     return 0;
101 }
View Code

http://poj.org/problem?id=3468

http://poj.org/problem?id=3264

http://acm.hdu.edu.cn/showproblem.php?pid=1166

posted @ 2019-01-22 08:25  XXrl  阅读(164)  评论(0编辑  收藏  举报