传送门:http://bailian.openjudge.cn/practice/4090/
【题解】
垃圾题目暴力能过???
splay,那个revolve相当于交换区间,瞎搞搞。
就这垃圾题目还tm卡常真是没话说了
加一坨rg和st,把回收队列改成自己写的栈就过了。。
6s-》4s
pkusc如果有这种题记得卡卡常。
# include <queue> # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 2e5 + 10; const int mod = 1e9+7; # define RG register # define ST static ST int n; ST int a[M], id[M], m; namespace Splay { ST int ch[M][2], fa[M], s[M], v[M], sz[M]; ST bool rev[M]; ST int tag[M], siz, rt; ST int re[M], rn; inline void clear() { siz = rn = 0; } # define ls ch[x][0] # define rs ch[x][1] inline void up(int x) { if(!x) return ; s[x] = v[x]; if(ls) s[x] = min(s[x], s[ls]); if(rs) s[x] = min(s[x], s[rs]); sz[x] = sz[ls] + sz[rs] + 1; } inline void pushrev(int x) { if(!x) return ; swap(ch[x][0], ch[x][1]); rev[x] ^= 1; } inline void pushtag(int x, int t) { tag[x] += t; s[x] += t, v[x] += t; } inline void down(int x) { if(!x) return ; if(rev[x]) { pushrev(ls); pushrev(rs); rev[x] ^= 1; } if(tag[x]) { pushtag(ls, tag[x]); pushtag(rs, tag[x]); tag[x] = 0; } } # undef ls # undef rs inline void rotate(int x, int &rt) { int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1; if(y == rt) rt = x; else ch[z][ch[z][1] == y] = x; fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z; ch[y][ls] = ch[x][rs]; ch[x][rs] = y; up(y), up(x); } int st[M]; inline void splay(int x, int &rt) { int stn = 0, tx = x; while(tx != rt) { st[++stn] = tx; tx = fa[tx]; } st[++stn] = tx; for (int i=stn; i; --i) down(st[i]); while(x != rt) { int y = fa[x], z = fa[y]; if(y != rt) { if((ch[y][0] == x) ^ (ch[z][0] == y)) rotate(x, rt); else rotate(y, rt); } rotate(x, rt); } } inline int find(int x, int rnk) { down(x); if(sz[ch[x][0]] + 1 == rnk) return x; if(sz[ch[x][0]] + 1 < rnk) return find(ch[x][1], rnk-sz[ch[x][0]]-1); else return find(ch[x][0], rnk); } // [u+1, v+1] inline int split(int u, int v) { int x = find(rt, u), y = find(rt, v+2); splay(x, rt); splay(y, ch[x][1]); return ch[y][0]; } inline void add(int u, int v, int d) { int x = split(u, v), y = fa[x]; pushtag(x, d); up(y), up(fa[x]); } inline void reverse(int u, int v) { int x = split(u, v), y = fa[x]; pushrev(x); up(y), up(fa[x]); } inline void gmin(int u, int v) { int x = split(u, v); printf("%d ", s[x]); } inline void revolve(int u, int v, int T) { T = T % (v-u+1); if(T == 0) return ; int x, y, xx, yy; // (u, v-T) (v-T+1, v) x = split(u, v-T), y = fa[x]; ch[y][0] = 0, fa[x] = 0; up(y); up(fa[y]); xx = find(rt, u+T), yy = find(rt, u+T+1); splay(xx, rt); splay(yy, ch[xx][1]); ch[yy][0] = x, fa[x] = yy; up(yy); up(fa[yy]); } inline void build(int l, int r, int f) { if(l>r) return; int mid = l+r>>1; int x = id[mid], lst = id[f]; if(l == r) { sz[x] = 1; v[x] = s[x] = a[l]; fa[x] = 0, ch[x][0] = ch[x][1] = 0; rev[x] = 0, tag[x] = 0; } else build(l, mid-1, x), build(mid+1, r, x); v[x] = a[mid]; fa[x] = lst; up(x); ch[lst][mid >= f] = x; } inline void insert(int u, int d) { int x; if(!rn) x = ++siz; else x = re[rn--]; v[x] = s[x] = d; sz[x] = 1; fa[x] = 0, ch[x][0] = ch[x][1] = 0; rev[x] = 0, tag[x] = 0; int X = find(rt, u+1), Y = find(rt, u+2); splay(X, rt); splay(Y, ch[X][1]); ch[Y][0] = x; fa[x] = Y; up(Y); up(X); // printf("%d ", sz[X]); } inline void del(int u) { int x = split(u, u), y = fa[x]; re[++rn] = x; ch[y][0] = 0; fa[x] = 0; sz[x] = s[x] = v[x] = rev[x] = tag[x] = 0; ch[x][0] = ch[x][1] = 0; up(y), up(fa[y]); // printf("%d ", sz[fa[y]]); } } int main() { ST int q, x, y, d; ST char str[23]; Splay::clear(); cin >> n; for (RG int i=2; i<=n+1; ++i) scanf("%d", a+i), id[i] = i; id[1] = 1, id[n+2] = n+2; a[1] = a[n+2] = 23333333; Splay::siz = n+2; Splay::build(1, n+2, 0); Splay::rt = n+3>>1; cin >> q; while(q--) { scanf("%s", str); if(!strcmp(str, "ADD")) { scanf("%d%d%d", &x, &y, &d); Splay::add(x, y, d); } if(!strcmp(str, "REVERSE")) { scanf("%d%d", &x, &y); Splay::reverse(x, y); } if(!strcmp(str, "REVOLVE")) { scanf("%d%d%d", &x, &y, &d); Splay::revolve(x, y, d); } if(!strcmp(str, "INSERT")) { scanf("%d%d", &x, &d); Splay::insert(x, d); } if(!strcmp(str, "DELETE")) { scanf("%d", &x); Splay::del(x); } if(!strcmp(str, "MIN")) { scanf("%d%d", &x, &y); Splay::gmin(x, y); } } return 0; }