题意:给出一段数列,任意区间加上一个整数v,任意区间查询。给出N个数,Q次操作。
线段树的题,延迟指针不更新到底就行了。
#include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define maxn 100005 long long sum[maxn<<2],col[maxn<<2]; void build(int rt,int l,int r) { col[rt]=0; if(l==r) { scanf("%lld",&sum[rt]); return; } int mid=(l+r)>>1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void update(int L,int R,long long c,int l,int r,int rt) { if(L<=l&&r<=R) { col[rt]+=c; sum[rt]+=(long long)(r-l+1)*c; return; } if(col[rt]!=0) { int m=(r-l+1); col[rt<<1]+=col[rt],col[rt<<1|1]+=col[rt]; sum[rt<<1]+=(long long)(m-(m>>1))*col[rt]; sum[rt<<1|1]+=(long long)(m>>1)*col[rt]; col[rt]=0; } int mid=(l+r)>>1; if(mid>=L) update(L,R,c,l,mid,rt<<1); if(mid<R) update(L,R,c,mid+1,r,rt<<1|1); sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } long long query(int L,int R,int l,int r,int rt) { if(L<=l&&r<=R) return sum[rt]; if(col[rt]!=0) { int m=(r-l+1); col[rt<<1]+=col[rt],col[rt<<1|1]+=col[rt]; sum[rt<<1]+=(long long)(m-(m>>1))*col[rt]; sum[rt<<1|1]+=(long long)(m>>1)*col[rt]; col[rt]=0; } int mid=(l+r)>>1; long long ret=0; if(mid>=L) ret+=query(L,R,l,mid,rt<<1); if(mid<R) ret+=query(L,R,mid+1,r,rt<<1|1); return ret; } int main() { int n,q,a,b; long long v; char c[2]; while(~scanf("%d%d",&n,&q)) { build(1,1,n); while(q--) { scanf("%s%d%d",c,&a,&b); if(c[0]=='Q') printf("%lld\n",query(a,b,1,n,1)); else scanf("%lld",&v),update(a,b,v,1,n,1); } } return 0; }
时间: 2024-10-23 05:49:56