线段树成段更新模板POJ3468 zkw以及lazy思想

别人树状数组跑几百毫秒 我跑 2500多

  1 #include<cstdio>
  2 #include<map>
  3 //#include<bits/stdc++.h>
  4 #include<vector>
  5 #include<stack>
  6 #include<iostream>
  7 #include<algorithm>
  8 #include<cstring>
  9 #include<cmath>
 10 #include<queue>
 11 #include<cstdlib>
 12 #include<climits>
 13 #define INF 0x3f3f3f3f
 14 using namespace std;
 15 typedef long long ll;
 16 typedef __int64 int64;
 17 const ll mood=1e9+7;
 18 const int64 Mod=998244353;
 19 const double eps=1e-9;
 20 const int MAXN=100010;
 21 const double PI=acos(-1.0);
 22 inline void rl(ll&num){
 23     num=0;ll f=1;char ch=getchar();
 24     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 25     while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
 26     num*=f;
 27 }
 28 inline void ri(int &num){
 29     num=0;int f=1;char ch=getchar();
 30     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 31     while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
 32     num*=f;
 33 }
 34 int getnum()//相邻的个位整数输入 如想分别保存1234 输入连续的1234 a[i]=getnum();就可以实现
 35 {
 36     char ch=getchar();
 37     while((ch<'0' || ch>'9') && ch!='-')
 38         ch=getchar();
 39     return (ch-'0');
 40 }
 41 inline void out(int x){ if(x<0) {putchar('-');  x*=-1;}if(x>9) out(x/10);    putchar(x%10+'0'); }
 42 ll sum[MAXN<<2],add[MAXN<<2];
 43 int n;
 44 void init(int _n)
 45 {
 46     n=1;
 47     while(n<_n) n*=2;
 48     for(int i=0;i<2*n-1;i++)
 49     {
 50         sum[i]=add[i]=0;
 51     }
 52 }
 53 void pushdown(int rt,int m)
 54 {
 55     if(add[rt])
 56     {
 57         add[rt*2+2] += add[rt];
 58         add[rt<<1|1] += add[rt];
 59         sum[rt*2+2] += add[rt] * (m - (m>>1));
 60         sum[rt<<1|1] += add[rt] * (m>>1);
 61         add[rt] = 0;
 62     }
 63 }
 64 void pushup(int rt)
 65 {
 66     sum[rt]=sum[rt*2+2]+sum[rt<<1|1];
 67 }
 68 void update(int a,int b,int c,int k,int l,int r)
 69 {
 70     if(r<=a||b<=l) return ;
 71     if(a<=l&&r<=b)
 72     {
 73         add[k]+=c;
 74         sum[k]+=(ll)c*(r-l);
 75         return ;
 76     }
 77     if(l+1==r) return;
 78     pushdown(k,r-l);
 79     int m=(l+r)/2;
 80     if(b<=m)
 81     {
 82         update(a,b,c,k*2+1,l,m);
 83     }
 84     else{
 85         if(l>m)update(a,b,c,k*2+2,m,r);
 86         else{
 87             update(a,b,c,k*2+1,l,m);
 88             update(a,b,c,k*2+2,m,r);
 89         }
 90     }
 91     pushup(k);
 92 }
 93 ll query(int a,int b,int k,int l,int r)
 94 {
 95     if(r<=a||b<=l) return 0;
 96     if(a<=l&&r<=b)
 97     {
 98         return sum[k];
 99     }
100     pushdown(k,r-l);
101     int m=(l+r)/2;
102     ll res=0;
103     if(b<=m)
104     {
105         res+=query(a,b,k*2+1,l,m);
106     }
107     else{
108         if(l>m)res+=query(a,b,k*2+2,m,r);
109         else{
110             res+=query(a,b,k*2+1,l,m);
111             res+=query(a,b,k*2+2,m,r);
112         }
113     }
114     return res;
115 }
116 void ad(int k,int a)
117 {
118     k+=n-1;
119     sum[k]=a;
120     while(k>0)
121     {
122         k=(k-1)/2;
123         sum[k]=sum[k*2+1]+sum[k*2+2];
124     }
125 }
126 int main()
127 {
128     int _n,m;
129     while(scanf("%d%d",&_n,&m)==2)
130     {
131         init(_n);
132         for(int i=1;i<=_n;i++)
133         {
134             int tem;
135             ri(tem);ad(i,tem);
136         }
137         char ch[2];
138 
139         int a,b,c;
140         while(m--)
141         {
142             scanf("%s",ch);
143             if(ch[0] == 'Q')
144             {
145                 scanf("%d %d", &a,&b);
146                 printf("%lld
",query(a,b+1,0,0,n));
147             }
148 
149             else
150             {
151                 scanf("%d %d %d",&a,&b,&c);
152                 update(a,b+1,c,0,0,n);
153             }
154         }
155         memset(add,0,sizeof(add));
156         memset(sum,0,sizeof(sum));
157     }
158     return 0;
159 }
View Code

等看能不能优化再写

原文地址:https://www.cnblogs.com/Geek-xiyang/p/5396902.html