线段树成段更新模板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\n",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 }
等看能不能优化再写