好累,一天写了三棵树
splay区间翻转、区间加法、区间求最大值
还是要记得注意边界条件,tr[0] = a[0] = mx[0] = -INF
诶下午物理考龊了估计要被老师切死
#include <iostream>
#include <cstdio>
#include <stack>
#define ls s[t][0]
#define rs s[t][1]
#define INF (1<<30)
#define N 200050
using namespace std;
int a[N],siz[N],tr[N],fa[N],s[N][2],d[N],mx[N],rev[N],ag[N];
int rt,cnt,n,m;
inline void update(int t) {
siz[t] = siz[ s[t][0] ] + siz[ s[t][1] ] + 1;
mx[t] = max( mx[ s[t][0] ] , mx[ s[t][1] ]);
mx[t] = max(mx[t],tr[t]);
}
void rot(int x,int &k) {
int y = fa[x] , z = fa[y] , l = (s[y][0] == x) ^ 1 , r = l ^ 1;
if (k == y) k = x; else { if (s[z][0] == y) s[z][0] = x; else s[z][1] = x; }
s[y][l] = s[x][r]; s[x][r] = y;
fa[x] = z; fa[y] = x; fa[ s[y][l] ] = y;
update(y); update(x);
}
void pdd(int t) {
if (rev[t]) {
rev[t] ^= 1; swap(s[t][0],s[t][1]);
rev[ s[t][0] ] ^= 1; rev[ s[t][1] ] ^= 1;
}
if (s[t][0]) mx[ls] += ag[t] , tr[ls] += ag[t] , ag[ls] += ag[t];
if (s[t][1]) mx[rs] += ag[t] , tr[rs] += ag[t] , ag[rs] += ag[t];
ag[t] = 0;
return ;
}
stack<int> sta;
void access(int x,int k) {
while (x != k) { sta.push(x); x = fa[x]; }
while (!sta.empty()) {
pdd(sta.top());
sta.pop();
}
}
void SPlay(int x,int &k) {
access(x,k);
while (x != k) {
int y = fa[x] , z = fa[y];
if (y != k) { if ((s[z][0] == y) ^ (s[y][0] == x)) rot(x,k); else rot(y,k); }
rot(x,k);
}
}
void build(int l,int r,int &t,int f) {
if (l > r) return ;
int mid = (l + r) >> 1;
fa[t = ++cnt] = f; d[mid] = t; siz[t] = 1; tr[t] = a[mid];
if (l == r) return ;
build(l,mid-1,s[t][0],t);
build(mid+1,r,s[t][1],t);
update(t);
}
int kth(int k,int t) {
pdd(t);
int tmp = siz[ s[t][0] ] + 1;
if (k == tmp) return t;
return tmp > k ? kth(k,s[t][0]) : kth(k-tmp,s[t][1]);
}
void solve() {
scanf("%d%d",&n,&m);
a[1] = -INF; a[n+2] = -INF; a[0] = -INF; tr[0] = -INF; mx[0] = -INF;
build(1,n+2,rt,0);
while (m--) {
int cmd,l,r; scanf("%d",&cmd);
scanf("%d%d",&l,&r); int u = kth(l,rt) , v = kth(r+2,rt);
SPlay(v,rt);
SPlay(u,s[v][0]);
int t = s[u][1];
if (cmd == 1) {
int k; scanf("%d",&k);
ag[t] += k; mx[t] += k; tr[t] += k;
}
if (cmd == 2) rev[t] ^= 1;
if (cmd == 3) printf("%d\n",mx[t]);
update(u); update(v);
}
return ;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("fuck.in","r",stdin);
freopen("fuck.out","w",stdout);
#endif
solve();
return 0;
}