poj 3468
经典线段树,大彻大悟了!!!
代码:
#include<iostream> #include<fstream> using namespace std; struct e{ int left,right; long long add; long long sum; }; e tree[400011]; long long a[100001]; long long build(int s,int t,int num){ long long i,j; tree[num].left=s; tree[num].right=t; tree[num].add=0; if(s!=t) { i=build(s,(s+t)/2,num*2); j=build((s+t)/2+1,t,num*2+1); } else { tree[num].sum=a[s]; return(a[s]); } tree[num].sum=i+j; return(tree[num].sum); } void insert(int s,int t,int add,int num){ if(s<=tree[num].left&&tree[num].right<=t) { tree[num].add+=add; tree[num].sum+=add*(tree[num].right-tree[num].left+1); return; } if(tree[num].add){ tree[num*2].sum+=tree[num].add*(tree[num*2].right-tree[num*2].left+1); tree[num*2+1].sum+=tree[num].add*(tree[num*2+1].right-tree[num*2+1].left+1); tree[num*2].add+=tree[num].add; tree[num*2+1].add+=tree[num].add; tree[num].add=0; } if(s<=(tree[num].left+tree[num].right)/2) insert(s,t,add,num*2); if(t>(tree[num].left+tree[num].right)/2) insert(s,t,add,num*2+1); tree[num].sum=tree[num*2].sum+tree[num*2+1].sum; } long long search(int s,int t,int num){ long long i=0,j=0; if(s<=tree[num].left&&tree[num].right<=t) { return(tree[num].sum); } if(tree[num].add){ tree[num*2].sum+=tree[num].add*(tree[num*2].right-tree[num*2].left+1); tree[num*2+1].sum+=tree[num].add*(tree[num*2+1].right-tree[num*2+1].left+1); tree[num*2].add+=tree[num].add; tree[num*2+1].add+=tree[num].add; tree[num].add=0; } if(s<=(tree[num].left+tree[num].right)/2) { i=search(s,t,num*2); } if(t>(tree[num].left+tree[num].right)/2) { j=search(s,t,num*2+1); } return(i+j); } int main(){ //ifstream cin("in.txt"); int i,j,k,n,m,p,t; char s; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) scanf("%lld",&a[i]); build(1,n,1); for(i=1;i<=m;i++) { scanf("\n%c",&s); if(s=='C') { scanf("%d%d%d",&j,&k,&p); if(j>k) {t=j;j=k;k=t;} insert(j,k,p,1); } else { scanf("%d%d",&j,&k); if(j>k) {t=j;j=k;k=t;} cout<<search(j,k,1)<<endl; } } return(0); }