http://poj.org/problem?id=3468
实现一个线段树,能够做到区间修改和区间查询和。
明显板子题。
#include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<iostream> using namespace std; typedef long long ll; inline ll read(){ ll X=0,w=0; char ch=0; while(ch<'0' || ch>'9') {w|=ch=='-';ch=getchar();} while(ch>='0' && ch<='9') X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } ll tree[400001],b[100001]; ll lazy[400001]; void build(int a,int l,int r){ lazy[a]=0; if(l==r){ tree[a]=b[l]; return; } int mid=(l+r)/2; build(a*2,l,mid); build(a*2+1,mid+1,r); tree[a]=tree[a*2]+tree[a*2+1]; return; } inline void push(int a,int l,int mid,int r){ lazy[a*2+1]+=lazy[a]; lazy[a*2]+=lazy[a]; tree[a*2+1]+=lazy[a]*(r-mid); tree[a*2]+=lazy[a]*(mid-l+1); lazy[a]=0; return; } ll wen(int a,int l,int r,int l1,int r1){ if(l1<=l&&r1>=r){ return tree[a]; } if (l1>r||r1<l) return 0; int mid=(l+r)/2; push(a,l,mid,r); return wen(a*2,l,mid,l1,r1)+wen(a*2+1,mid+1,r,l1,r1); } void gai(int a,int l,int r,int l1,int r1,int add){ if (l1>r||r1<l) return; if(l1<=l&&r1>=r){ lazy[a]+=add; tree[a]+=add*(r-l+1); return; } int mid=(l+r)/2; push(a,l,mid,r); gai(a*2,l,mid,l1,r1,add); gai(a*2+1,mid+1,r,l1,r1,add); tree[a]=tree[a*2]+tree[a*2+1]; return; } int main(){ int m=read(); int ha=read(); for(int i=1;i<=m;i++){ b[i]=read(); } build(1,1,m); for(int i=1;i<=ha;i++){ char w; cin>>w; if(w=='C'){ int a1=read(); int a2=read(); int a3=read(); gai(1,1,m,a1,a2,a3); }else{ int x=read(); int y=read(); printf("%lld ",wen(1,1,m,x,y)); } } return 0; }