这个应该就是kac说的splay三部曲的第二个题了。。。
超级水啊,不知道为什么始终有一种写数据结构题的渴望,也许是长代码敲的爽?
写完这个题基本上所有的splay处理区间问题就都不怕了,不过其实这个题只是前两个splay的和啊。。。
有一个标记没传下来wa了半天还好有对拍。。。。
很短的代码。。。似乎写慢了
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define MAX 50000+20
using namespace std;
int child[MAX][2],add[MAX],res[MAX],value[MAX],father[MAX],n,m,root,tot;
int size[MAX],Max[MAX],a[MAX];
void up(int x)
{
Max[x]=value[x];
size[x]=1;
if(child[x][0])
{
Max[x]=max(Max[x],Max[child[x][0]]);
size[x]+=size[child[x][0]];
}
if(child[x][1])
{
Max[x]=max(Max[x],Max[child[x][1]]);
size[x]+=size[child[x][1]];
}
}
void down(int x)
{
if(!x)
return;
if(add[x])
{
if(child[x][0])
{
value[child[x][0]]+=add[x];
add[child[x][0]]+=add[x];
Max[child[x][0]]+=add[x];
}
if(child[x][1])
{
value[child[x][1]]+=add[x];
add[child[x][1]]+=add[x];
Max[child[x][1]]+=add[x];
}
add[x]=0;
}
if(!res[x])
return;
if(child[x][0])
res[child[x][0]]^=1;
if(child[x][1])
res[child[x][1]]^=1;
res[x]=0;
swap(child[x][0],child[x][1]);
return;
}
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;
up(q);
return;
}
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[y][0]==y))
rotate(y);
else
rotate(x);
}
if(aim==0)
root=x;
up(x);
}
void build(int &x,int l,int r)
{
if(l>r)
{
x=0;
return;
}
int mid=(l+r)>>1;
x=++tot;
size[x]=1;
res[x]=add[x]=0;
value[x]=Max[x]=0;
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;
up(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;
}
int main()
{
size[0]=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n+1;i++)
a[i]=i-1;
root=tot=0;
build(root,1,n+2);
while(m--)
{
int contorl;
scanf("%d",&contorl);
if(contorl==1)
{
int l,r,num;
scanf("%d%d%d",&l,&r,&num);
splay(select(l));
splay(select(r+2),root);
int now=child[child[root][1]][0];
add[now]+=num;
value[now]+=num;
Max[now]+=num;
}
if(contorl==2)
{
int l,r;
scanf("%d%d",&l,&r);
splay(select(l));
splay(select(r+2),root);
int now=child[child[root][1]][0];
res[now]=1;
}
if(contorl==3)
{
int l,r;
scanf("%d%d",&l,&r);
splay(select(l));
splay(select(r+2),root);
int now=child[child[root][1]][0];
printf("%d\n",Max[now]);
}
}
return 0;
}