伸展树裸题,做了几题后已经不需要调了,像前几次经常调个好久。。听说可持久化treap更好用,调起来方便,下次学一下。
code:
#include
#include
using namespace std;
#define lson x->ch[0]
#define rson x->ch[1]
#define ket (root->ch[1]->ch[0])
const int maxn = 300000+5;
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
struct NODE{
NODE *pre, *ch[2];
int val, G[2], sz, id, on;
void up() {
sz = ch[0]->sz + ch[1]->sz + 1;
G[on] = gcd(val, gcd(ch[0]->G[on], ch[1]->G[on]));
G[!on] = gcd(ch[0]->G[!on], ch[1]->G[!on]);
}
};
struct Splaytree {
int top;
NODE node[maxn], *null, *root;
void Rotate(NODE *x, int c) {
NODE *y = x->pre;
y->ch[!c] = x->ch[c];
if(x->ch[c] != null) x->ch[c]->pre = y;
x->pre = y->pre;
if(y->pre != null) y->pre->ch[ y->pre->ch[1]==y] = x;
x->ch[c] = y; y->pre = x;
y->up();
}
void Splay(NODE *x, NODE *go) {
while(x->pre != go) {
if(x->pre->pre == go) Rotate(x, x->pre->ch[0]==x);
else {
NODE *y = x->pre, *z = y->pre;
int f = z->ch[1] == y;
if(y->ch[f] == x) Rotate(y, !f);
else Rotate(x, f);
Rotate(x, !f);
}
}
x->up();
if(go == null) root = x;
}
void RTO(int k, NODE *go) {
NODE *x = root;
while(lson->sz != k) {
if(lson->sz > k) x = lson;
else {
k -= lson->sz + 1;
x = rson;
}
}
Splay(x, go);
}
int a[maxn], b[maxn];
NODE* newnode(int val, int on, NODE *f) {
NODE *x = &node[++top];
x->id = top; x->sz = 1;
lson = rson = null;
x->on = on; x->val = x->G[on] = val;
x->G[!on] = 0; x->pre = f;
return x;
}
NODE *build(int l, int r, NODE *f) {
if(l > r) return null;
int mid = (l + r)/2;
NODE *x = newnode(a[mid], b[mid], f);
lson = build(l, mid-1, x);
rson = build(mid+1, r, x);
x->up();
return x;
}
void init(int n) {
null = &node[0];
null->sz = null->G[0] = null->G[0] = null->val = 0;
top = 0;
root = newnode(0, 0, null);
root->ch[1] = newnode(0, 0, root);
for(int i = 0;i < n; i++) scanf("%d%d", &a[i], &b[i]);
ket = build(0, n-1, root->ch[1]);
root->ch[1]->up(); root->up();
}
void Get(int l, int r) {
RTO(l-1, null);
RTO(r+1, root);
}
void Query() {
int l, r, on;
scanf("%d%d%d", &l, &r, &on);
Get(l, r);
int ans = ket->G[on];
if(!ans) puts("-1");
else printf("%d\n", ans);
}
void Insert() {
int i, val, on;
scanf("%d%d%d", &i, &val, &on);
RTO(i, null);
RTO(i+1, root);
ket = newnode(val, on, root->ch[1]);
root->ch[1]->up(); root->up();
}
void Delete() {
int i;
scanf("%d", &i);
Get(i, i);
ket = null;
root->ch[1]->up(); root->up();
}
void RR() {
int i;
scanf("%d", &i);
Get(i, i);
ket->on ^= 1; swap(ket->G[0], ket->G[1]);
root->ch[1]->up(); root->up();
}
void Modify() {
int i, v;
scanf("%d%d", &i, &v);
Get(i, i);
ket->val = ket->G[ket->on] = v;
root->ch[1]->up(); root->up();
}
}spt;
int main() {
int n, m;
while(scanf("%d%d", &n, &m) != -1) {
spt.init(n);
for(int i = 0;i < m; i++) {
char op[5];
scanf("%s", op);
if(op[0] == 'Q') spt.Query();
else if(op[0] == 'I') spt.Insert();
else if(op[0] == 'D') spt.Delete();
else if(op[0] == 'R') spt.RR();
else spt.Modify();
}
}
return 0;
}