题意:维护一个长为n(n <= 100000)的序列,支持6种操作,区间加,区间反转,区间旋转,单点插入,单点删除,区间求最小值,操作个数m <= 100000.
分析:
裸的splay,不完全缩行后代码长度1913B,poj第一...
感谢zrt神犇对我的splay进行指导。
#include <cstdio>
#include <algorithm>
using namespace std;
#define l(x) t[x].s[0]
#define r(x) t[x].s[1]
#define f(x) t[x].p
#define ky l(r(rt))
#define lc(x) t[f(x)].s[1] == x
#define st(a,b,c) if(a) t[a].s[c] = b; if(b) f(b) = a;
const int N = 200010, inf = 0x3fffffff;
char op[10];
int n, q, tt, rt, x, y, z, a[N>>1];
struct nd {
int s[2], v, sz, p, mi, fl, ad;
}t[N];
void pu(int x) {
t[x].mi = min(t[x].v, min(t[l(x)].mi, t[r(x)].mi));
t[x].sz = t[l(x)].sz + t[r(x)].sz + 1;
}
void pd(int x) {
int d = t[x].ad;
if(l(x)) t[l(x)].ad += d, t[l(x)].mi += d, t[l(x)].v += d;
if(r(x)) t[r(x)].ad += d, t[r(x)].mi += d, t[r(x)].v += d;
t[x].ad = 0;
if(t[x].fl) t[l(x)].fl ^= 1, t[r(x)].fl ^= 1, swap(l(x), r(x)), t[x].fl = 0;
}
void bd(int l, int r, int p, int &x) {
if(l > r) return;
int m = (l + r) >> 1;
t[x=++tt].p = p, t[x].v = a[m];
bd(l, m-1, x, l(x)), bd(m+1, r, x, r(x));
pu(x);
}
int rk(int k, int x) {
pd(x);
if(t[l(x)].sz + 1 == k) return x;
if(t[l(x)].sz >= k) return rk(k, l(x));
return rk(k-t[l(x)].sz-1, r(x));
}
void rot(int x) {
int y = f(x), z = f(y), lx = lc(x), ly = lc(y);
st(y, t[x].s[!lx], lx);
st(z, x, ly);
st(x, y, !lx);
pu(y);
}
void sp(int x, int g = 0) {
while(f(x) != g) rot(x);
pu(x);
if(!g) rt = x;
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
t[0].mi = t[0].v = inf;
bd(0, n+1, 0, rt);
scanf("%d", &q);
while(q--) {
scanf("%s", op);
if(op[0] == 'A') {
scanf("%d%d%d", &x, &y, &z);
sp(rk(x, rt)), sp(rk(y+2, rt), rt);
t[ky].v += z, t[ky].mi += z, t[ky].ad += z;
pu(r(rt)), pu(rt);
} else if(op[0] == 'M') {
scanf("%d%d", &x, &y);
sp(rk(x, rt)), sp(rk(y+2, rt), rt);
printf("%d\n", t[ky].mi);
} else if(op[0] == 'I') {
scanf("%d%d", &x, &y);
sp(rk(x+1, rt)), sp(rk(x+2, rt), rt);
ky = ++tt;
t[ky].p = r(rt), t[ky].v = t[ky].mi = y, t[ky].sz = 1;
pu(r(rt)), pu(rt);
} else if(op[0] == 'D') {
scanf("%d", &x);
sp(rk(x, rt)), sp(rk(x+2, rt), rt);
t[ky].p = 0, ky = 0;
pu(r(rt)), pu(rt);
} else if(op[3] == 'E') {
scanf("%d%d", &x, &y);
sp(rk(x, rt)), sp(rk(y+2, rt), rt);
t[ky].fl ^= 1;
} else {
scanf("%d%d%d", &x, &y, &z);
z %= y-x+1;
sp(rk(y-z+1, rt)), sp(rk(y+2, rt), rt);
int tp = ky; ky = 0;
pu(r(rt)), pu(rt);
sp(rk(x, rt)), sp(rk(x+1, rt), rt);
st(r(rt), tp, 0);
pu(r(rt)), pu(rt);
}
}
return 0;
}