简单的伸展树题。。。节点记录一下两种gcd状态即可。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 300005 #define maxm 400005 #define eps 1e-10 #define mod 1000000007 #define lowbit(x) (x&(-x)) #define ls o<<1 #define rs o<<1 | 1 #define lson o<<1, L, mid #define rson o<<1 | 1, mid+1, R typedef long long LL; //typedef int LL; using namespace std; int gcd(int a, int b) { if(!b) return a; else return gcd(b, a%b); } struct node { int s, v, x, g[2]; node *ch[2], *fa; int cmp(int x) { if(x == ch[0]->s + 1) return -1; if(x > ch[0]->s + 1) return 1; else return 0; } void maintain(void) { s = ch[0]->s + ch[1]->s + 1; g[0] = g[1] = 0; if(x) g[1] = gcd(g[1], v); else g[0] = gcd(g[0], v); g[0] = gcd(gcd(g[0], ch[0]->g[0]), ch[1]->g[0]); g[1] = gcd(gcd(g[1], ch[0]->g[1]), ch[1]->g[1]); } }*null, *root, C[maxn], *top; void rotate(node* &o, bool d) { node *p = o->fa; p->ch[d^1] = o->ch[d], o->fa = p->fa; if(p->fa != null) { if(p->fa->ch[0] == p) p->fa->ch[0] = o; else p->fa->ch[1] = o; } if(p->ch[d^1] != null) p->ch[d^1]->fa = p; p->fa = o, o->ch[d] = p; p->maintain(), o->maintain(); } void splay(node* &o, int k) { int d = o->cmp(k); while(d != -1) { if(d == 1) { k -= o->ch[0]->s + 1; o = o->ch[1]; } else o = o->ch[0]; d = o->cmp(k); } node *p; while(o->fa != null) { p = o->fa; if(p->ch[0] == o) { if(p != null && p->fa->ch[0] == p) rotate(p, true); rotate(o, true); } else { if(p != null && p->fa->ch[1] == p) rotate(p, false); rotate(o, false); } } } node* merge(node *left, node *right) { splay(left, left->s); left->ch[1] = right; right->fa = left; left->maintain(); return left; } void split(node *o, int k, node* &left, node* &right) { splay(o, k); right = o->ch[1]; right->fa = null; o->ch[1] = null; left = o; left->maintain(); } int n, m; char s[20]; void init(void) { top = C; null = top++; null->v = null->s = null->x = 0; null->g[0] = null->g[1] = 0; null->ch[0] = null->ch[1] = null->fa = NULL; root = top++; root->v = root->s = root->x = 0; root->ch[0] = root->ch[1] = null; root->maintain(); } void build(void) { node *p; int v, x; for(int i = 1; i <= n; i++) { scanf("%d%d", &v, &x); p = top++; p->v = v, p->x = x; p->ch[0] = root; p->ch[1] = p->fa = null; p->g[0] = p->g[1] = 0; root->fa = p; root = p; root->maintain(); } } void work(void) { int k, v, x, a, b; node *p, *mid, *left, *right; while(m--) { scanf("%s", s); if(s[0] == 'M') { scanf("%d%d", &k, &x); splay(root, k+1); root->v = x; } if(s[0] == 'R') { scanf("%d", &k); splay(root, k+1); root->x^=1; } if(s[0] == 'Q') { scanf("%d%d%d", &a, &b, &x); split(root, a, left, p); split(p, b-a+1, mid, right); if(mid->g[x] == 0) printf("-1\n"); else printf("%d\n", mid->g[x]); root = merge(merge(left, mid), right); } if(s[0] == 'I') { scanf("%d%d%d", &k, &v, &x); mid = top++; mid->v = v, mid->x = x; mid->ch[0] = mid->ch[1] = mid->fa = null; mid->maintain(); split(root, k+1, left, right); root = merge(merge(left, mid), right); } if(s[0] == 'D') { scanf("%d", &k); split(root, k, left, p); split(p, 1, mid, right); root = merge(left, right); } } } int main(void) { while(scanf("%d%d", &n, &m)!=EOF) { init(); build(); work(); } return 0; }