早以前就用线段树做过了这个水题。。。
今天为了练习splay,作为splay处理区间的第二题。。。。写了一下午一直tle
准备睡的时候一试结果a了。。。原来是int×int给爆了,转下long long就好了
但是在bsoj上还是过不了啊splay常数那么大就给1s!!!!!
刷不动了。。。就差重写读入了。。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define ll long long
#define MAX 100000+50
using namespace std;
int n,m,a[MAX],value[MAX],child[MAX][2],size[MAX];
int tot,root,father[MAX];
ll add[MAX],he[MAX];
void build(int &x,int l,int r)
{
if(l>r)
{
x=0;
return;
}
int mid=(l+r)>>1;
x=++tot;
size[x]=1;
add[x]=0;
he[x]=a[mid];
value[x]=a[mid];
build(child[x][0],l,mid-1);
build(child[x][1],mid+1,r);
if(child[x][0])
father[child[x][0]]=x;
if(child[x][1])
father[child[x][1]]=x;
he[x]=value[x]+he[child[x][0]]+he[child[x][1]];
size[x]=size[child[x][0]]+size[child[x][1]]+1;
}
void down(int x)
{
if(!x)
return;
value[x]+=add[x];
add[child[x][0]]+=add[x];
add[child[x][1]]+=add[x];
if(child[x][0])
he[child[x][0]]+=((long long)add[x]*size[child[x][0]]);
if(child[x][1])
he[child[x][1]]+=((long long)add[x]*size[child[x][1]]);
add[x]=0;
}
void rotate(int p)
{
int q=father[p],y=father[q],x=(child[q][1]==p);
down(q);
down(p);
father[child[q][x]=child[p][x^1]]=q;
father[child[p][x^1]=q]=p;
father[p]=y;
if(y)
child[y][child[y][1]==q]=p;
size[q]=size[child[q][0]]+size[child[q][1]]+1;
he[q]=he[child[q][0]]+he[child[q][1]]+value[q];
//size[p]=size[child[p][0]]+size[child[p][1]]+1;
//he[p]=he[child[p][0]]+he[child[p][1]]+value[p];
}
void splay(int x,int aim=0)
{
down(x);
for(int y;(y=father[x])!=aim;rotate(x))
if(father[y]!=aim)
{
if((child[y][0]==x)==(child[father[y]][0]==y))
rotate(y);
else
rotate(x);
}
if(aim==0)
root=x;
size[x]=size[child[x][0]]+size[child[x][1]]+1;
he[x]=he[child[x][0]]+he[child[x][1]]+value[x];
}
int select(int x)
{
int t=root;
while(1)
{
down(t);
if(size[child[t][0]]+1==x)
break;
if(x<=size[child[t][0]])
t=child[t][0];
else
{
x-=size[child[t][0]]+1;
t=child[t][1];
}
}
return t;
}
void debug()
{
printf("i father he value add size child_l child_r\n");
for(int i=0;i<=tot;i++)
printf("%d %d %d %d %d %d %d %d\n",i,father[i],he[i],value[i],add[i],size[i],child[i][0],child[i][1]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=2;i<=n+1;i++)
scanf("%d",&a[i]);
root=tot=0;
build(root,1,n+2);
while(m--)
{
getchar();
char ch;
scanf("%c",&ch);
if(ch=='Q')
{
int l,r;
scanf("%d%d",&l,&r);
splay(select(l));
splay(select(r+2),root);
printf("%lld\n",he[child[child[root][1]][0]]);
}
else
{
int l,r,nu;
scanf("%d%d%d",&l,&r,&nu);
splay(select(l));
splay(select(r+2),root);
add[child[child[root][1]][0]]+=nu;
he[child[child[root][1]][0]]+=((long long)nu*size[child[child[root][1]][0]]);
}
}
return 0;
}