AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1251
【题解】
splay的练习题目。
切掉模板之后应该没有问题了。
注意mx[0]=-INF
/*************
bzoj 1251
by chty
2016.12.26
*************/
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
using namespace std;
#define FILE "read"
#define MAXN 50010
#define inf 0x7fffffff
#define up(i,j,n) for(int i=j;i<=n;i++)
#define dn(i,j,n) for(int i=j;i>=n;i--)
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
namespace INIT{
char buf[1<<15],*fs,*ft;
inline char getc(){return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;}
inline int read(){
int x=0,f=1; char ch=getc();
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getc();}
while(isdigit(ch)) {x=x*10+ch-'0'; ch=getc();}
return x*f;
}
}using namespace INIT;
int n,m,root;
namespace Splay_Tree{
int son[MAXN][2],f[MAXN],v[MAXN],size[MAXN],mx[MAXN],delta[MAXN],vis[MAXN];
bool get(int x){return son[f[x]][1]==x;}
void updata(int x){
size[x]=size[son[x][0]]+size[son[x][1]]+1;
mx[x]=max(mx[son[x][0]],mx[son[x][1]]);
mx[x]=max(mx[x],v[x]);
}
void rotate(int x){
int y=f[x],z=f[y],which=get(x);
son[y][which]=son[x][which^1]; f[son[y][which]]=y;
son[x][which^1]=y; f[y]=x; f[x]=z;
if(z) son[z][son[z][1]==y]=x;
updata(y); updata(x);
}
void splay(int x,int k){
for(int y;(y=f[x]);rotate(x)){
if(x==k) break;
else if(y==k) {rotate(x); break;}
else if(f[y]==k) {rotate(get(x)==get(y)?y:x); rotate(x); break;}
else rotate(get(x)==get(y)?y:x);
}
if(k==root) root=x;
}
void pushdown(int x){
if(delta[x]){
if(son[x][0]) delta[son[x][0]]+=delta[x],v[son[x][0]]+=delta[x],mx[son[x][0]]+=delta[x];
if(son[x][1]) delta[son[x][1]]+=delta[x],v[son[x][1]]+=delta[x],mx[son[x][1]]+=delta[x];
delta[x]=0;
}
if(vis[x]){
swap(son[x][0],son[x][1]);
vis[son[x][0]]^=1; vis[son[x][1]]^=1; vis[x]=0;
}
}
int find(int x){
int now=root;
while(1){
if(vis[now]||delta[now]) pushdown(now);
int temp=size[son[now][0]];
if(x<=temp) now=son[now][0];
else{
if(x==temp+1) return now;
x-=temp+1;
now=son[now][1];
}
}
}
void build(int l,int r,int p){
if(l>r) return;
if(l==r){son[p][l>=p]=l;f[l]=p;size[l]=1;return;}
int mid=(l+r)>>1;
build(l,mid-1,mid); build(mid+1,r,mid);
son[p][mid>=p]=mid; f[mid]=p; updata(mid);
}
void change(int l,int r,int value){
int x=find(l),y=find(r+2);
splay(x,root); splay(y,son[root][1]);
int z=son[y][0];
delta[z]+=value; mx[z]+=value; v[z]+=value;
}
void rever(int l,int r){
int x=find(l),y=find(r+2);
splay(x,root); splay(y,son[root][1]);
vis[son[y][0]]^=1;
}
void query(int l,int r){
int x=find(l),y=find(r+2);
splay(x,root); splay(y,son[root][1]);
printf("%d\n",mx[son[y][0]]);
}
}using namespace Splay_Tree;
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
n=read(); m=read(); mx[0]=-inf;
build(1,n+2,0); root=(n+3)>>1;
up(i,1,m){
int flag=read(),l=read(),r=read(),value;
switch(flag){
case 1:value=read();change(l,r,value);break;
case 2:rever(l,r);break;
case 3:query(l,r);break;
}
}
return 0;
}