版权声明:希望有人转(^_^) https://blog.csdn.net/Sunshine_cfbsl/article/details/52234656
这题基本上就是
AC后就能领悟到
Splay Tree模板戳这里
题目大意:
对于一个数列
- ADD x y D:给数列
{Ax,...,Ay} 中的每一个数都增加D - REVERSE x y: 将数列
{Ax,...,Ay} 翻转过来 - REVOLVE x y T:将数列
{Ax,...,Ay} 中每一个数向右移动T 位,其中第y 位向右移动一位后到x 的位置 - INSERT x P:在
Ax 后插入数字P - DELETE x:删除
Ax - MIN x y:求数列
{Ax,...,Ay} 的最小值
一眼就可以看出用
之前一直拒绝使用
代码如下:
/*
ID: Sunshine_cfbsl
LANG: C++
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN = 200010, INF = 1000000000;
int n, m;
struct Splay_Tree {
int fa[MAXN], ch[MAXN][2], v[MAXN], size[MAXN], flag[MAXN], r, pn, Min[MAXN];
bool rev[MAXN];
void clear(int x) {
r = pn = size[1] = 1;
Min[0] = INF;
v[1] = Min[1] = x;
}
void update(int p, int e, bool rever) {
if(p == 0) return;
flag[p] += e;
v[p] += e;
Min[p] += e;
if(rever) {
swap(ch[p][0], ch[p][1]);
rev[p] ^= true;
}
}
void push_down(int p) {
if(flag[p] || rev[p]) {
update(ch[p][0], flag[p], rev[p]);
update(ch[p][1], flag[p], rev[p]);
flag[p] = rev[p] = 0;
}
}
void maintain(int p) {
Min[p] = min(min(Min[ch[p][0]], Min[ch[p][1]]), v[p]);
size[p] = size[ch[p][0]] + size[ch[p][1]] + 1;
}
void Rotate(int p, bool t) {
int f = fa[p];
push_down(f);
push_down(p);
fa[ch[f][t^1] = ch[p][t]] = f;
fa[ch[fa[f]][ch[fa[f]][1]==f] = p] = fa[f];
ch[fa[f] = p][t] = f;
maintain(f);
}
void splay(int x, int end) {
push_down(x);
while(fa[x] != end) {
int p = fa[x];
if(fa[p] == end) {
Rotate(x, x==ch[p][0]);
break;
}
bool f = x==ch[p][0], f1 = p==ch[fa[p]][0], f2 = p==ch[fa[p]][1];
Rotate(f?f1?p:x:f2?p:x, f);
Rotate(x, f1);
}
maintain(x);
if(end == 0) r = x;
}
void init(int y) {
fa[ch[r][1] = ++pn] = r;
v[pn] = Min[pn] = y;
size[pn] = 1;
splay(pn, 0);
}
int find(int x) {
int p = r;
while(size[p] ^ 1) {
push_down(p);
if(size[ch[p][0]]+1 == x) break;
if(x > size[ch[p][0]]) {
x -= (size[ch[p][0]]+1);
p = ch[p][1];
}
else p = ch[p][0];
}
return p;
}
int query(int s, int t) {
splay(find(s), 0);
splay(find(t), r);
return Min[ch[ch[r][1]][0]];
}
void add(int s, int t, int e) {
splay(find(s), 0);
splay(find(t), r);
update(ch[ch[r][1]][0], e, 0);
}
void del(int p) {
splay(p = find(p), 0);
splay(find(size[ch[r][0]]), r);
r = ch[r][0];
fa[r] = 0;
fa[ch[r][1] = ch[p][1]] = r;
maintain(r);
}
void insert(int x, int value) {
splay(find(x), 0);
splay(find(x+1), r);
int u = ch[r][1];
fa[ch[u][0] = ++pn] = u;
size[pn] = 1;
v[pn] = Min[pn] = value;
maintain(u);
maintain(r);
}
void reverse(int s, int t) {
splay(find(s), 0);
splay(find(t), r);
update(ch[ch[r][1]][0], 0, 1);
}
void revolve(int s, int t, int k) {
k = (k%(t-s+1)+(t-s+1))%(t-s+1);
splay(find(t-k), 0);
splay(find(t+1), r);
int u = ch[ch[r][1]][0];
fa[u] = ch[ch[r][1]][0] = 0;
maintain(ch[r][1]);
maintain(r);
splay(find(s-1), 0);
splay(find(s), r);
ch[fa[u] = ch[r][1]][0] = u;
maintain(ch[r][1]);
maintain(r);
}
}tree;
int main() {
int i, tmp, x, y, d;
char str[20];
scanf("%d", &n);
tree.clear(INF);
for(i = 1; i <= n; i++) {
scanf("%d", &tmp);
tree.init(tmp);
}
tree.init(INF);
scanf("%d", &m);
for(i = 1; i <= m; i++) {
scanf("%s", str);
if(str[0] == 'A') {
scanf("%d%d%d", &x, &y, &d);
if(x > y) swap(x, y);
tree.add(x, y+2, d);
}
if(str[0] == 'R' && str[3] == 'E') {
scanf("%d%d", &x, &y);
if(x > y) swap(x, y);
tree.reverse(x, y+2);
}
if(str[0] == 'R' && str[3] == 'O') {
scanf("%d%d%d", &x, &y, &d);
if(x > y) swap(x, y);
tree.revolve(x+1, y+1, d);
}
if(str[0] == 'I') {
scanf("%d%d", &x, &d);
tree.insert(x+1, d);
}
if(str[0] == 'D') {
scanf("%d", &x);
tree.del(x+1);
}
if(str[0] == 'M') {
scanf("%d%d", &x, &y);
if(x > y) swap(x, y);
printf("%d\n", tree.query(x, y+2));
}
}
return 0;
}