题目地址:http://poj.org/problem?id=3468
区间更新,加上某值,区间求和,用splay tree做,可以当模版了。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define N 200010 #define Key_value ch[ch[root][1]][0] using namespace std; int key[N],n; int pre[N]; int ch[N][2],tot,root,node[N]; ll add[N],size[N];ll sum[N];int data[N]; void newnode(int &r,int k,int fa) { r=++tot; ch[r][0]=ch[r][1]=0; pre[r]=fa; key[r]=sum[r]=k; add[r]=0; size[r]=1; } void push_up(int r) { size[r]=size[ch[r][0]]+size[ch[r][1]]+1; sum[r]=add[r]+key[r]+sum[ch[r][0]]+sum[ch[r][1]]; } void push_down(int r) { if(add[r]) { key[r]+=add[r]; add[ch[r][0]]+=add[r]; add[ch[r][1]]+=add[r]; sum[ch[r][0]]+=(ll)size[ch[r][0]]*add[r]; sum[ch[r][1]]+=(ll)size[ch[r][1]]*add[r]; add[r]=0; } } void build(int &r,int L,int R,int fa) { if(L>R) return; int mid=(L+R)/2; newnode(r,data[mid],fa); build(ch[r][0],L,mid-1,r); build(ch[r][1],mid+1,R,r); push_up(r); } void Init() { tot=root=0; ch[0][0]=ch[0][1]=pre[0]=size[0]=sum[0]=add[0]=0; newnode(root,-1,0); newnode(ch[root][1],-1,root); //size[root]=2; for(int i=0;i<n;i++) scanf("%d",&data[i]); build(Key_value,0,n-1,ch[root][1]); push_up(ch[root][1]); push_up(root); } void Rotate(int x,int kind) { int y=pre[x]; push_down(y); push_down(x); ch[y][!kind]=ch[x][kind]; pre[ch[x][kind]]=y; if(pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x; pre[x]=pre[y]; ch[x][kind]=y; pre[y]=x; push_up(y); } void splay(int r,int goal) { push_down(r); while(pre[r]!=goal) { if(pre[pre[r]]==goal) Rotate(r,ch[pre[r]][0]==r); else { int y=pre[r]; int kind=(ch[pre[y]][0]==y); if(ch[y][kind]==r) { Rotate(r,!kind); Rotate(r,kind); } else { Rotate(y,kind); Rotate(r,kind); } } } push_up(r); if(goal==0) root=r; } void RotateTo(int k,int goal) { int r=root; push_down(r); while(size[ch[r][0]]!=k) { if(k<size[ch[r][0]]) r=ch[r][0]; else { k-=(size[ch[r][0]]+1); r=ch[r][1]; } push_down(r); } splay(r,goal); } void update(int l,int r,int c) { RotateTo(l-1,0); RotateTo(r+1,root); add[Key_value]+=c; sum[Key_value]+=(ll)c*size[Key_value]; } void query(int l,int r) { RotateTo(l-1,0); RotateTo(r+1,root); printf("%lld\n",sum[Key_value]); } char str[3]; int main() { int m,l,r,c; scanf("%d%d",&n,&m); Init(); while(m --) { char op[2]; scanf("%s",op); if(op[0] == 'Q') { scanf("%d%d",&l,&r); query(l,r); } else { scanf("%d%d%d",&l,&r,&c); update(l,r,c); } } return 0; }