题目地址: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;
}