zoukankan      html  css  js  c++  java
  • SPOJ QTREE6

    https://www.spoj.com/problems/QTREE6/

    考虑对0颜色和1颜色分别维护定根(no reverse)lct。

    即在(c[x])的lct上给(x)(fa[x])连一条边。

    修改直接link、cut。

    查询x的话,考虑access走到最上面的点,这个点实际上和x是不连通的,但是它的子节点(x方向的)的子树就是联通块大小。

    所以lct要顺便维护子树和。

    Code:

    #include<bits/stdc++.h>
    #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
    #define ff(i, x, y) for(int i = x, _b = y; i <  _b; i ++)
    #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
    #define ll long long
    #define pp printf
    #define hh pp("
    ")
    using namespace std;
    
    const int N = 1e5 + 5;
    
    int n, x, y;
    
    vector<int> e[N];
    #define pb push_back
    #define si size()
    
    int fa[N];
    
    void dg(int x) {
    	ff(_y, 0, e[x].si) {
    		int y = e[x][_y];
    		if(y == fa[x]) continue;
    		fa[y] = x;
    		dg(y);
    	}
    }
    
    int id[N][2], td, id2[N];
    
    struct lct {
    	#define x0 t[x][0]
    	#define x1 t[x][1]
    	int fa[N], pf[N], t[N][2], s[N], ps[N];
    	int lr(int x) { return t[fa[x]][1] == x;}
    	void upd(int x) {
    		if(x) s[x] = 1 + ps[x] + s[x0] + s[x1];
    	}
    	void ro(int x) {
    		int y = fa[x], k = lr(x);
    		t[y][k] = t[x][!k]; if(t[x][!k]) fa[t[x][!k]] = y;
    		fa[x] = fa[y]; if(fa[y]) t[fa[y]][lr(y)] = x;
    		fa[y] = x, t[x][!k] = y, pf[x] = pf[y];
    		upd(y); upd(x);
    	}
    	void sp(int x, int y) {
    		for(; fa[x] != y; ro(x)) if(fa[fa[x]] != y)
    			ro(lr(x) == lr(fa[x]) ? fa[x] : x);
    	}
    	void ac(int x) {
    		int xx = x;
    		for(int y = 0; x; ) {
    			sp(x, 0), fa[x1] = 0, pf[x1] = x;
    			ps[x] += s[x1];
    			
    			x1 = y, fa[y] = x, pf[y] = 0;
    			ps[x] -= s[y];
    			
    			upd(x), y = x, x = pf[x];
    		}
    		sp(xx, 0);
    	}
    	void link(int x, int y) {
    		ac(y); ac(x);
    		pf[x] = y; ps[y] += s[x];
    		upd(y);
    		ac(x);
    	}
    	void cut(int x, int y) {
    		ac(x); sp(y, 0);
    		t[y][1] = fa[x] = pf[x] = 0;
    		upd(y);
    	}
    	int fl(int x) { return x0 ? fl(x0) : x;}
    	int qry(int x) {
    		ac(x);
    		int y = fl(x);
    		sp(y, 0);
    		return s[t[y][1]];
    	}
    } l[2];
    
    int c[N];
    
    int m, op;
    
    int main() {
    	scanf("%d", &n);
    	fo(i, 1, n - 1) {
    		scanf("%d %d", &x, &y);
    		e[x].pb(y); e[y].pb(x);
    	}
    	dg(1);
    	fa[1] = n + 1;
    	fo(i, 1, n + 1) fo(j, 0, 1)
    		l[j].s[i] = 1;
    	fo(i, 1, n) {
    		c[i] = 1;
    		l[1].link(i, fa[i]);
    	}
    	scanf("%d", &m);
    	fo(i, 1, m) {
    		scanf("%d %d", &op, &x);
    		if(op == 1) {
    			l[c[x]].cut(x, fa[x]);
    			c[x] = !c[x];
    			l[c[x]].link(x, fa[x]);
    		} else {
    			pp("%d
    ", l[c[x]].qry(x));
    		}
    	}
    }
    
  • 相关阅读:
    zendstudio文件编码修改问题
    js去掉字符串前后空格的五种方法
    一组PHP可逆加密解密算法
    Discuz! 经典加密解密函数
    卡号 不足位数 补0
    关于jquery跨域请求方法
    JQuery实现当鼠标停留在某区域3秒后执行
    ajax async
    mysql replace 替换函数
    php curl 发送 json 数据
  • 原文地址:https://www.cnblogs.com/coldchair/p/12919594.html
Copyright © 2011-2022 走看看