传送门
和(POJ) 3580 SuperMemo比略逊一筹。
#include<bits/stdc++.h>
#define il inline
#define inf 0x3f3f3f3f
using namespace std;
const int N=1e5+5;
template <typename _Tp> il void read(_Tp&x) {
char ch;bool flag=0;x=0;
while(ch=getchar(),!isdigit(ch)) if(ch=='-')flag=1;
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
if(flag) x=-x;
}
//******************//
int root,tot=0;
int ch[N][2],val[N],par[N],sz[N],SPadd[N],mx[N];
bool rev[N];
il void pushup(int x) {
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
mx[x]=val[x];
if(ch[x][0]) mx[x]=max(mx[x],mx[ch[x][0]]);
if(ch[x][1]) mx[x]=max(mx[x],mx[ch[x][1]]);
}
il bool ws(int x) { return ch[par[x]][1]==x;}
il void pushdown(int x) {
if(rev[x]) {
swap(ch[x][0],ch[x][1]);
rev[ch[x][0]]^=1;
rev[ch[x][1]]^=1;
rev[x]=0;
}
if(SPadd[x]!=0) {
if(ch[x][0]){
val[ch[x][0]]+=SPadd[x];
mx[ch[x][0]]+=SPadd[x];
SPadd[ch[x][0]]+=SPadd[x];
}
if(ch[x][1]){
val[ch[x][1]]+=SPadd[x];
mx[ch[x][1]]+=SPadd[x];
SPadd[ch[x][1]]+=SPadd[x];
}
SPadd[x]=0;
}
}
il void rotate(int x) {
int f=par[x],ff=par[f],k=ws(x),w=ch[x][k^1];
ch[f][k]=w,par[w]=f;
ch[ff][ws(f)]=x,par[x]=ff;
ch[x][k^1]=f,par[f]=x;
pushup(f),pushup(x);
}
il void splay(int x,int goal=0) {
while(par[x]!=goal) {
int f=par[x],ff=par[f];
if(ff!=goal) {
if(ws(x)==ws(f)) rotate(f);
else rotate(x);
}
rotate(x);
}
if(!goal) root=x;
}
il int newnode(int key,int fa) {
tot++;
ch[tot][1]=ch[tot][0]=0;
sz[tot]=1,mx[tot]=key,val[tot]=key;
SPadd[tot]=0,par[tot]=fa,rev[tot]=0;
return tot;
}
il int kth(int k) { //获得第k个节点的tot值
k++; //因为有虚点
int x=root;
while(1) {
pushdown(x);
if(k==sz[ch[x][0]]+1) break;
if(k>sz[ch[x][0]]+1) {
k-=sz[ch[x][0]]+1;
x=ch[x][1];
} else x=ch[x][0];
}
return x;
}
il void add(int L,int R,int d) {
// cout<<"add "<<L<<" "<<R<<" "<<d<<endl;
L=kth(L-1),R=kth(R+1);
splay(L,0),splay(R,L);
val[ch[R][0]]+=d;
mx[ch[R][0]]+=d;
SPadd[ch[R][0]]+=d;
pushup(R),pushup(L);
}
il void reverse(int L,int R) {
L=kth(L-1),R=kth(R+1);
splay(L,0),splay(R,L);
rev[ch[R][0]]^=1;
}
il int qmax(int L,int R) {
L=kth(L-1),R=kth(R+1);
splay(L,0),splay(R,L);
return mx[ch[R][0]];
}
il int sbuild(int l,int r,int fa) {
if(l>r) return 0;
int x=newnode(0,fa);
int mid=(l+r)>>1;
ch[x][0]=sbuild(l,mid-1,x);
ch[x][1]=sbuild(mid+1,r,x);
pushup(x);
return x;
}
int n,m;
int main() {
read(n),read(m);
root=sbuild(0,n+1,0);
int op,l,r,x;
for(int i=1; i<=m; ++i) {
read(op),read(l),read(r);
if(op==1) read(x),add(l,r,x);
else if(op==2) reverse(l,r);
else if(op==3) printf("%d\n",qmax(l,r));
}
return 0;
}