题意:维护一个长为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; }