Splay的序列操作
注意:
更新的时候,要先确定子树不为空在进行更新。
空指针的mx值要设为-inf
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 50010;
struct node{
int num, val, size, turn, mx, add;
node *pre, *ch[2];
void update(){
size = ch[0]->size + ch[1]->size + 1;
mx = max(max(ch[0]->mx, ch[1]->mx), val);
}
int wh(){return pre->ch[0] == this ? 0 : 1;}
void set_ch(int wh, node *child);
}pool[maxn], *root, *null;
void node::set_ch(int wh, node *child){
ch[wh] = child;
if(child != null) child->pre = this;
update();
}
int cnt, n, m;
node *get(int num, int val){
node *now = &pool[++cnt];
now->mx = now->val = val, now->num = num, now->size = 1;
now->pre = now->ch[0] = now->ch[1] = null;
now->turn = now->add = 0;
return now;
}
void down(node *now){
if(now->add != 0){
if(now->ch[0] != null) {
now->ch[0]->add += now->add;
now->ch[0]->mx += now->add;
now->ch[0]->val += now->add;
}
if(now->ch[1] != null){
now->ch[1]->add += now->add;
now->ch[1]->mx += now->add;
now->ch[1]->val += now->add;
}
now->add = 0;
}
if(now->turn != 0){
now->turn = 0;
swap(now->ch[0]->ch[0], now->ch[0]->ch[1]);
swap(now->ch[1]->ch[0], now->ch[1]->ch[1]);
now->ch[0]->turn ^= 1;
now->ch[1]->turn ^= 1;
}
}
node *find(int num){
node *now = root;
int rank = num;
while(now != null){
down(now);
if(now->ch[0]->size+1 == rank) return now;
else if(now->ch[0]->size+1 < rank){
rank -= now->ch[0]->size+1;
now = now->ch[1];
}else now = now->ch[0];
}
return null;
}
void rotate(node *now){
node *fa = now->pre, *gra = now->pre->pre;
int wh = now->wh();
fa->set_ch(wh, now->ch[wh^1]);
now->set_ch(wh^1, fa);
now->pre = gra;
if(gra != null) gra->ch[gra->ch[0] == fa ? 0 : 1] = now;
}
void splay(node *now, node *tar){
for( ; now->pre != tar; rotate(now))
if(now->pre->pre != tar)
now->wh() == now->pre->wh() ? rotate(now->pre) : rotate(now);
if(tar == null) root = now;
}
void insert(int num, int val){
node *now = root, *last = null;
while(now != null){
last = now;
if(now->num > num) now = now->ch[0];
else now = now->ch[1];
}
now = get(num, val);
if(last == null) root = now;
else{
if(num < last->num) last->set_ch(0, now);
else last->set_ch(1, now);
splay(now, null);
}
}
int main(){
null = pool;
null->add = null->num = 0, null->mx = -2e9;
null->turn = null->size = null->val = 0;
null->ch[0] = null->ch[1] = null->pre = null;
root = null;
scanf("%d%d", &n, &m);
insert(0, 0), insert(n+1, 0);
for(int i = 1; i <= n; i ++) insert(i, 0);
for(int i = 1; i <= m; i ++){
int a, b, c, d;
scanf("%d%d%d", &a, &b, &c);
if(a == 1){
scanf("%d", &d);
node *l = find(b), *r = find(c+2);
splay(r, null), splay(l, r);
l->ch[1]->add += d;
l->ch[1]->val += d;
l->ch[1]->mx += d;
}else if(a == 2){
node *l = find(b), *r = find(c+2);
splay(r, null), splay(l, r);
l->ch[1]->turn ^= 1;
swap(l->ch[1]->ch[0], l->ch[1]->ch[1]);
}else{
node *l = find(b), *r = find(c+2);
splay(r, null), splay(l, r);
printf("%d\n", l->ch[1]->mx);
}
}
return 0;
}