zoukankan      html  css  js  c++  java
  • ZOJ3765 Lights Splay树

    非常裸的一棵Splay树,需要询问的是区间gcd,但是区间上每个数分成了两种状态,做的时候分别存在val[2]的数组里就好。区间gcd的时候基本上不支持区间的操作了吧。。不然你一个区间里加一个数gcd都不知道怎么维护了,所以维护点的gcd是比较简单的,题目存在删除和增加,所以Splay树无误了。删除一个结点或区间的方法是先把它get出来,然后令root->ch[1]->ch[0]=null,记得每次操作完要提根。

    #pragma warning(disable:4996)
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<iostream>
    #define ll long long
    #define maxn 401000
    using namespace std;
    
    int n, q;
    
    int gcd(int a, int b)
    {
    	while (a&&b) { a %= b; a ^= b; b ^= a; a ^= b; }
    	return a + b;
    }
    
    struct Node
    {
    	Node *ch[2], *p;
    	int size, val[2], gval[2];
    	int status;
    	Node(){
    		size = 0; val[0] = val[1] = 0; status = 0; gval[0] = gval[1] = 0;
    	}
    	bool d() {
    		return this == p->ch[1];
    	}
    	void setc(Node *c, int d){
    		ch[d] = c; c->p = this;
    	}
    	void cvalIt(int cval){
    		val[status] = cval;
    		gval[status] = gcd(val[status],gcd(ch[0]->gval[status], ch[1]->gval[status]));
    	}
    	void cstaIt(){
    		swap(val[status ^ 1], val[status]);
    		gval[status] = gcd(ch[0]->gval[status], ch[1]->gval[status]);
    		gval[status ^ 1] = gcd(gval[status ^ 1], gcd(ch[0]->gval[status ^ 1], ch[1]->gval[status ^ 1]));
    		status ^= 1;
    	}
    	void upd(){
    		size = ch[0]->size + ch[1]->size + 1;
    		for (int i = 0; i < 2; i++){
    			gval[i] = gcd(gcd(ch[0]->gval[i], ch[1]->gval[i]), val[i]);
    		}
    	}
    }Tnull,*null=&Tnull;
    
    Node mem[maxn], *C = mem;
    
    Node*make(int v, int sta){
    	C->ch[0] = C->ch[1] = null;
    	C->size = 1;
    	C->val[sta] = v; C->val[sta ^ 1] = 0;
    	C->gval[sta] = v; C->gval[sta ^ 1] = 0;
    	C->status = sta;
    	return C++;
    }
    
    int ax[maxn], bx[maxn];
    
    Node*build(int l, int r)
    {
    	if (l >= r) return null;
    	int m = (l + r) >> 1;
    	Node *t = make(ax[m], bx[m]);
    	t->setc(build(l, m), 0);
    	t->setc(build(m + 1, r), 1);
    	t->upd();
    	return t;
    }
    
    Node *root;
    void rot(Node*t) {
    	Node*p = t->p;
    	//p->relax();
    	//t->relax();
    	int d = t->d();
    	p->p->setc(t, p->d());
    	p->setc(t->ch[!d], d);
    	t->setc(p, !d);
    	p->upd();
    	if (p == root)
    		root = t;
    }
    
    void splay(Node*t, Node*f = null) {
    	while (t->p != f) {
    		if (t->p->p == f)
    			rot(t);
    		else
    			t->d() == t->p->d() ? (rot(t->p), rot(t)) : (rot(t), rot(t));
    	}
    	t->upd();
    }
    
    Node* select(int k) {
    	for (Node*t = root;;) {
    		//t->relax();
    		int c = t->ch[0]->size;
    		if (k == c)
    			return t;
    		if (k > c)
    			k -= c + 1, t = t->ch[1];
    		else
    			t = t->ch[0];
    	}
    }
    
    Node*&get(int l, int r) { //[l,r)
    	Node*L = select(l - 1);
    	Node*R = select(r);
    	splay(L);
    	splay(R, L);
    	return R->ch[0];
    }
    
    void print(Node* x)
    {
    	if (x == null) return;
    	print(x->ch[0]);
    	printf(" %d", x->val[0]);
    	print(x->ch[1]);
    }
    
    
    
    
    
    int main()
    {
    	while (~scanf("%d%d", &n, &q))
    	{
    		for (int i = 1; i <= n; i++){
    			scanf("%d%d", &ax[i], &bx[i]);
    		}
    		C = mem;
    		ax[0] = ax[n + 1] = 0; bx[0] = bx[n + 1] = 0;
    		root = build(0, n + 2); root->p = null;
    		char type[3];
    		int li, ri, si,vi;
    		for (int i = 0; i < q; i++){
    			scanf("%s", type);
    			if (type[0] == 'Q'){
    				scanf("%d%d%d", &li, &ri, &si);
    				Node* &t=get(li, ri+1);
    				if (t->gval[si]) {
    					printf("%d
    ", t->gval[si]);
    				}
    				else puts("-1");
    			}
    			else if (type[0] == 'I'){
    				scanf("%d%d%d", &li, &vi, &si);
    				Node *&t = get(li, li + 1);
    				t->ch[1] = make(vi, si);
    				splay(t);
    			}
    			else if (type[0] == 'D' ){
    				scanf("%d", &li);
    				Node *&t = get(li, li+1);
    				root->ch[1]->ch[0] = null;
    				splay(root->ch[1]);
    			}
    			else if (type[0] == 'R'){
    				scanf("%d", &li);
    				Node *&t = get(li, li + 1);
    				t->cstaIt();
    				splay(t);
    			}
    			else if (type[0] == 'M'){
    				scanf("%d%d", &li, &vi);
    				Node *&t = get(li, li + 1);
    				t->cvalIt(vi);
    				splay(t);
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Spring boot mvn
    软考
    java
    webserver代理生成本地类的两种方式
    行转列语句,记录一下
    React.PureComponent浅比较理解
    关于职业规划和职场规则以及未来发展发方向
    程序员的一天
    代码commit规范
    element UI 使用总结
  • 原文地址:https://www.cnblogs.com/chanme/p/3578978.html
Copyright © 2011-2022 走看看