zoukankan      html  css  js  c++  java
  • QTREE 系列

    • tps 以下代码均为LCT
      LCT专题???

    QTREE 1

    树链剖分 or LCT 板子

    没啥可说的,这题 LCT 跑的还没树链剖分 + 线段树快

    (code)

    #include<bits/stdc++.h>
    using namespace std;
    #define rg register
    inline int read(){
    	rg char ch = getchar();
    	rg int x = 0, f = 0;
    	while(! isdigit(ch)) f |= (ch == '-'), ch = getchar();
    	while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    	return f ? -x : x; 
    }
    const int N = 2e5 + 5;
    int id[N];
    int f[N], son[N][2], maxi[N], cnt, v[N], lazy[N], g[N];
    inline int new_node(int val){
    	v[++cnt] = val;
    	maxi[cnt] =val;
    	return cnt;
    }
    #define ls son[p][0]
    #define rs son[p][1]
    #define fs(p) (son[f[p]][1] == p)
    #define nroot(p) (son[f[p]][0] == p || son[f[p]][1] == p)
    #define max(a, b) ((a) > (b) ? (a) : (b))
    inline void up(int p){
    	maxi[p] = max(v[p], max(maxi[ls], maxi[rs]));
    }
    inline void ros(int p){
    	int fa = f[p], ffa = f[fa];
    	int c = fs(p);
    	if(nroot(fa)) son[ffa][fs(fa)] = p; f[p] = ffa;
    	son[fa][c] = son[p][c ^ 1]; f[son[p][c ^ 1]] = fa;
    	son[p][c ^ 1] = fa; f[fa] = p;
    	up(fa); up(p);
    }
    int s[N], stop;
    inline void addtag(int p){
    	swap(ls, rs);
    	lazy[p] ^= 1;
    }
    inline void pushdown(int p){
    	if(lazy[p]){
    		if(ls) addtag(ls);
    		if(rs) addtag(rs);
    		lazy[p] = 0;
    	}
    }
    inline void splay(int p){
    	int fa;
    	s[++stop] = fa = p;
    	while(nroot(fa)) s[++stop] = fa = f[fa];
    	while(stop) pushdown(s[stop--]);
    	while(nroot(p)){
    		fa = f[p];
    		if(nroot(fa)) ros(fs(fa) ^ fs(p) ? p : fa);
    		ros(p);
    	}
    }
    inline void access(int p){
    	for(int pl = 0; p; p = f[pl = p])
    		splay(p), rs = pl, up(p);
    }
    inline int findroot(int p){
    	access(p);
    	splay(p);
    	while(ls) pushdown(p), p = ls;
    	splay(p);
    	return p;
    }
    inline void makeroot(int p){
    	access(p);
    	splay(p);
    	addtag(p);
    }
    inline void split(int x, int y){
    	makeroot(x);
    	access(y);
    	splay(y);
    }
    inline void link(int x, int y){
    	makeroot(x);
    	if(findroot(y) ^ x) f[x] = y;
    }
    inline void work(){
    	//memset(son, 0, sizeof son); cnt = 0;
    	//memset(id, 0, sizeof id);
    	int n = read();
    	for(int now, x, y, z, i = 1; i < n; ++i){
    		x = read(), y = read(), z = read();
    		if(!id[x]) id[x] = new_node(0);
    		if(!id[y]) id[y] = new_node(0);
    		g[i] = now = new_node(z);
    		link(id[x], now);
    		link(now, id[y]);
    	}
    	char *s = new char[15];
    	scanf("%s", s);
    	int x, y, z;
    	while(s[0] ^ 'D'){
    		if(s[0] == 'Q'){
    			x = read(), y = read();
    			split(id[x], id[y]);
    			printf("%d
    ",maxi[id[y]]);
    		}else{
    			x = read(), z = read();
    			makeroot(g[x]);
    			v[g[x]] = z;
    			up(g[x]);
    		}
    		scanf("%s", s);
    	}
    }
    		
    signed main(){
    	work();
    	//int T = read();
    	//while(T--) work();
    	return 0;
    }
    /*
    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE
    
    1
    
    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE
    */
    

    QTREE 2

    LCT + 平衡树找第 K 大

    (code)

    #include<bits/stdc++.h>
    using namespace std;
    #define rg register
    inline int read(){
    	rg char ch = getchar();
    	rg int x = 0, f = 0;
    	while(! isdigit(ch)) f |= (ch == '-'), ch = getchar();
    	while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    	return f ? -x : x; 
    }
    const int N = 2e5 + 5;
    int id[N];
    int f[N], son[N][2], sum[N], cnt, v[N], lazy[N], g[N], sz[N], del[N], back[N];
    inline int new_node(int val){
    	v[++cnt] = val;
    	sum[cnt] = val;
    	return cnt;
    }
    #define ls son[p][0]
    #define rs son[p][1]
    #define fs(p) (son[f[p]][1] == p)
    #define nroot(p) (son[f[p]][0] == p || son[f[p]][1] == p)
    #define max(a, b) ((a) > (b) ? (a) : (b))
    inline void up(int p){
    	sum[p] = sum[ls] + sum[rs] + v[p];
    	sz[p] = del[p] + sz[ls] + sz[rs];
    }
    inline void ros(int p){
    	int fa = f[p], ffa = f[fa];
    	int c = fs(p);
    	if(nroot(fa)) son[ffa][fs(fa)] = p; f[p] = ffa;
    	son[fa][c] = son[p][c ^ 1]; f[son[p][c ^ 1]] = fa;
    	son[p][c ^ 1] = fa; f[fa] = p;
    	up(fa); up(p);
    }
    int s[N], stop;
    inline void addtag(int p){
    	swap(ls, rs);
    	lazy[p] ^= 1;
    }
    inline void pushdown(int p){
    	if(lazy[p]){
    		if(ls) addtag(ls);
    		if(rs) addtag(rs);
    		lazy[p] = 0;
    	}
    }
    inline void splay(int p){
    	int fa;
    	s[++stop] = fa = p;
    	while(nroot(fa)) s[++stop] = fa = f[fa];
    	while(stop) pushdown(s[stop--]);
    	while(nroot(p)){
    		fa = f[p];
    		if(nroot(fa)) ros(fs(fa) ^ fs(p) ? p : fa);
    		ros(p);
    	}
    }
    inline void access(int p){
    	for(int pl = 0; p; p = f[pl = p])
    		splay(p), rs = pl, up(p);
    }
    inline int findroot(int p){
    	access(p);
    	splay(p);
    	while(ls) pushdown(p), p = ls;
    	splay(p);
    	return p;
    }
    inline void makeroot(int p){
    	access(p);
    	splay(p);
    	addtag(p);
    }
    inline void split(int x, int y){
    	makeroot(x);
    	access(y);
    	splay(y);
    }
    inline void link(int x, int y){
    	makeroot(x);
    	if(findroot(y) ^ x) f[x] = y;
    }
    inline int kth(int p, int k){
    	while(true){
    		if(sz[ls] >= k) p = ls;
    		else if(sz[ls] == k - 1 && del[p]) return back[p];
    		else k -= sz[ls] + del[p], p = rs;
    	}
    }
    int n;
    inline void work(){
    	for(int i = 1; i <= cnt; ++i) son[i][0] = son[i][1] = 0; cnt = 0;
    	for(int i = 1; i <= n; ++i) id[i] = 0;
    	int n = read();
    	for(int x, y, z, i = 1; i < n; ++i){
    		x = read(), y = read(), z = read();
    		if(!id[x]) id[x] = new_node(0), back[cnt] = x, del[cnt] = sz[cnt] = 1;
    		if(!id[y]) id[y] = new_node(0), back[cnt] = y, del[cnt] = sz[cnt] = 1;
    		g[i] = new_node(z);
    		del[cnt] = sz[cnt] = 0;
    		link(id[x], g[i]);
    		link(g[i], id[y]);
    	}
    	char *s = new char[15];
    	scanf("%s", s);
    	int x, y, z;
    	while(s[1] ^ 'O'){
    		if(s[0] == 'D'){
    			x = read(), y = read();
    			split(id[x], id[y]);
    			printf("%d
    ",sum[id[y]]);
    		}else{
    			x = id[read()], y = id[read()]; z = read();
    			split(x, y);
    			printf("%d
    ", kth(y, z));
    		}
    		scanf("%s", s);
    	}
    }
    		
    signed main(){
    	int T = read();
    	while(T--) work();
    	return 0;
    }
    /*
    */
    

    QTREE 3

    虽然这题可以不翻转, 但我还是写了

    记录一个最近点和最远点, 序列翻转的话需要交换这两个值

    (code)

    #include<bits/stdc++.h>
    using namespace std;
    #define rg register
    inline int read(){
    	rg char ch = getchar();
    	rg int x = 0, f = 0;
    	while(! isdigit(ch)) f |= (ch == '-'), ch = getchar();
    	while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    	return f ? -x : x; 
    }
    const int N = 2e5 + 5;
    int id[N];
    int f[N], son[N][2], find1[N], find2[N], cnt, lazy[N], del[N];
    #define ls son[p][0]
    #define rs son[p][1]
    #define fs(p) (son[f[p]][1] == p)
    #define nroot(p) (son[f[p]][0] == p || son[f[p]][1] == p)
    #define max(a, b) ((a) > (b) ? (a) : (b))
    inline void up(int p){
    	if(find1[ls]) find1[p] = find1[ls];
    	else if(del[p]) find1[p] = p;
    	else find1[p] = find1[rs];
    	
    	if(find2[rs]) find2[p] = find2[rs];
    	else if(del[p]) find2[p] = p;
    	else find2[p] = find2[ls];
    }
    inline void ros(int p){
    	int fa = f[p], ffa = f[fa];
    	int c = fs(p);
    	if(nroot(fa)) son[ffa][fs(fa)] = p; f[p] = ffa;
    	son[fa][c] = son[p][c ^ 1]; f[son[p][c ^ 1]] = fa;
    	son[p][c ^ 1] = fa; f[fa] = p;
    	up(fa); up(p);
    }
    int s[N], stop;
    #define swap(a, b) (a ^= b ^= a ^= b)
    inline void addtag(int p){
    	swap(ls, rs);
    	swap(find1[p], find2[p]);
    	lazy[p] ^= 1;
    }
    inline void pushdown(int p){
    	if(lazy[p]){
    		if(ls) addtag(ls);
    		if(rs) addtag(rs);
    		lazy[p] = 0;
    	}
    }
    inline void splay(int p){
    	int fa;
    	s[++stop] = fa = p;
    	while(nroot(fa)) s[++stop] = fa = f[fa];
    	while(stop) pushdown(s[stop--]);
    	while(nroot(p)){
    		fa = f[p];
    		if(nroot(fa)) ros(fs(fa) ^ fs(p) ? p : fa);
    		ros(p);
    	}
    	//up(p);
    }
    inline void access(int p){
    	for(int pl = 0; p; p = f[pl = p])
    		splay(p), rs = pl, up(p);
    }
    inline int findroot(int p){
    	access(p);
    	splay(p);
    	while(ls) pushdown(p), p = ls;
    	splay(p);
    	return p;
    }
    inline void makeroot(int p){
    	access(p);
    	splay(p);
    	addtag(p);
    }
    inline void split(int x, int y){
    	makeroot(x);
    	access(y);
    	splay(y);
    }
    inline void link(int x, int y){
    	makeroot(x);
    	if(findroot(y) ^ x) f[x] = y;
    }
    inline void work(){
    	int n = read(), m = read();
    	for(int x, y, i = 1; i < n; ++i){
    		x = read(), y = read();
    		link(x, y);
    	}
    	int s;
    	int x;
    	while(m--){
    		s = read();
    		if(s){
    			x = read();
    			split(1, x);
    			printf("%d
    ", find1[x] ? find1[x] : -1);
    		}else{
    			x = read();
    			access(x);
    			splay(x);
    			del[x] ^= 1;
    			up(x);
    		}
    	}
    			
    }
    		
    signed main(){
    	work();
    	return 0;
    }
    

    QTREE 4

    动态点分治 + 堆

    建出点分树后每个点放个堆

    删除的话就开两个堆, 懒惰删除

    QTREE 5

    这题需要维护子树最小值, 加上翻转后维护过于麻烦, 考虑不翻转

    维护两个值

    1 -> (lmn) : 在当前链上最高的点到一个白点的最近距离

    2 -> (rmn) : 在当前链上最低的点到一个白点的最近距离

    这样当一个点( (x) )和根连接成链( (access) )的时候,(x) 就是最低点, (rmn) 就是答案

    为了求出这个, 我们还要维护子树最小值, 就个对每个点开个 (multiset)

    (code)

    #include<iostream>
    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<set>
    using namespace std;
    #define rg register
    inline int read(){
    	rg char ch = getchar();
    	rg int x = 0, f = 0;
    	while(! isdigit(ch)) f |= (ch == '-'), ch = getchar();
    	while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    	return f ? -x : x;
    }
    const int N = 1e5 + 5;
    int son[N][2], f[N], lmn[N], rmn[N], sz[N], col[N];
    multiset<int> s[N];
    int head[N], nxt[N << 1], ver[N << 1], tot;
    inline void add(int x, int y){
    	ver[++tot] = y;
    	nxt[tot] = head[x];
    	head[x] = tot;
    }
    #define ls son[p][0]
    #define rs son[p][1]
    #define fs(p) (son[f[p]][1] == p)
    #define nroot(p) (son[f[p]][1] == p || son[f[p]][0] == p)
    #define inf 0x3f3f3f3f
    inline int get(int p){
    	return s[p].empty() ? inf : *s[p].begin();
    }
    inline int max(int a, int b){ return a > b ? a : b; }
    inline int min(int a, int b){ return a < b ? a : b; }
    inline void up(int p){
    	sz[p] = sz[ls] + sz[rs] + 1;
    	lmn[p] = min(lmn[ls], sz[ls] + min(get(p), min(col[p] ? 0 : inf, lmn[rs] + 1)));
    	rmn[p] = min(rmn[rs], sz[rs] + min(get(p), min(col[p] ? 0 : inf, rmn[ls] + 1)));
    }
    inline void ros(int p){
    	int fa = f[p], ffa = f[fa];
    	int c = fs(p);
    	if(nroot(fa)) son[ffa][fs(fa)] = p; f[p] = ffa;
    	son[fa][c] = son[p][c ^ 1]; f[son[p][c ^ 1]] = fa;
    	son[p][c ^ 1] = fa; f[fa] = p;
    	up(fa); // up(p);
    }
    inline void splay(int p){
    	int fa;
    	while(nroot(p)){
    		fa = f[p];
    		if(nroot(fa)) ros(fs(fa) ^ fs(p) ? p : fa);
    		ros(p);
    	}
    	up(p);
    }
    inline void access(int p){
    	for(int y = 0; p; p = f[y = p]){
    		splay(p);
    		if(rs) s[p].insert(lmn[rs] + 1);
    		if(y) s[p].erase(s[p].find(lmn[y] + 1));
    		rs = y;
    		up(p);
    	}
    }
    void dfs(int x){
    	sz[x] = 1;
    	for(int y , i = head[x]; i; i = nxt[i]){
    		if((y = ver[i]) == f[x]) continue;
    		s[x].insert(inf + 1);
    		f[y] = x;
    		dfs(y);
    	}
    }
    int n, m;
    int main(){
    	n = read();
    	for(int x, y, i = 1; i < n; ++i){
    		x = read(), y = read();
    		add(x, y); add(y, x);
    	}
    	memset(lmn, 0x3f, sizeof lmn);
    	memset(rmn, 0x3f, sizeof rmn);	
    	dfs(1);
    	m = read();
    	int op, x;
    	while(m--){
    		op = read(), x = read();
    		switch(op){
    			case 0 :
    				access(x);
    				splay(x);
    				col[x] ^= 1;
    				up(x);
    				break;
    			case 1 :
    				access(x);
    				splay(x);
    				printf("%d
    ", rmn[x] >= inf ? -1 : rmn[x]);
    		}
    	}
    			
    	return 0;
    }
    

    QTREE 6

    LCT 维护染色联通块, 连通块大小就是答案

    先考虑暴力

    开两颗 LCT, 维护子树大小

    当一个点改变颜色时, 就把它和与它相连的同色点断开, 异色点连接, 改变颜色

    如果图是菊花图, 这种做法就去世了

    正解

    通过暴力, 我们有了初步想法, 要通过维护子树大小维护连通块大小

    既然点不行, 就考虑边

    让一个点父亲边成为它的颜色, 把同一种颜色的边放到同一棵 LCT 上, 这样对于其中一棵 LCT 上的一颗树, 除了根节点以外其它都是同一种颜色

    我们查询只需要把 (x) (access) , 找到 (x) 的根, 这时根的右儿子的大小就是答案

    因为 1 号节点没父亲边, 我们为了方便维护就给他加个假父亲

    (code)

    #include<iostream>
    #include<cstdio>
    #include<cctype>
    #include<cstdlib>
    using namespace std;
    #define rg register
    inline int read(){
    	rg char ch = getchar();
    	rg int x = 0, f = 0;
    	while(! isdigit(ch)) f |= (ch == '-'), ch = getchar();
    	while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    	return f ? -x : x;
    }
    const int N = 1e5 + 5, M = N << 1;
    int head[N], nxt[M], ver[M], tot, col[N], fa[N];
    inline void add(int x, int y){
    	ver[++tot] = y;
    	nxt[tot] = head[x];
    	head[x] = tot;
    }
    struct LCT{
    	int son[N][2], f[N], sz[N], szl[N];
    	#define ls son[p][0]
    	#define rs son[p][1]
    	#define fs(p) (son[f[p]][1] == p)
    	#define nroot(p) (son[f[p]][0] == p || son[f[p]][1] == p)
    	inline void up(int p){
    		sz[p] = sz[ls] + sz[rs] + szl[p] + 1;
    	}
    	inline void prepro(int n){
    		for(int i = 1; i <= n; ++i) sz[i] = 1;
    	}
    	inline void ros(int p){
    		int fa = f[p], ffa = f[fa];
    		int c = fs(p);
    		if(nroot(fa)) son[ffa][fs(fa)] = p; f[p] = ffa;
    		son[fa][c] = son[p][c ^ 1]; f[son[p][c ^ 1]] = fa;
    		son[p][c ^ 1] = fa; f[fa] = p;
    		up(fa);
    	}
    	inline void splay(int p){
    		static int fa;
    		while(nroot(p)){
    			fa = f[p];
    			if(nroot(fa)) ros(fs(fa) ^ fs(p) ? p : fa);
    			ros(p);
    		}
    		up(p);
    	}
    	inline void access(int p){
    		for(int y = 0; p; p = f[y = p]){
    			splay(p);
    			szl[p] += sz[rs];
    			szl[p] -= sz[y];
    			rs = y;
    			up(p);
    		}
    	}
    	inline int findroot(int p){
    		access(p);
    		splay(p);
    		while(ls) p = ls;
    		splay(p);
    		return p;
    	}
    	inline void link(int x){
    		splay(x);
    		int y = f[x] = fa[x];
    		access(y);
    		splay(y);
    		szl[y] += sz[x]; sz[y] += sz[x];
    	}
    	inline void cut(int p){
    		access(p);
    		splay(p);
    		ls = f[ls] = 0;
    		up(p);
    	}
    	inline int query(int x){
    		x = findroot(x);
    		return sz[son[x][1]];
    	}
    }lct[2];
    int n, m;
    void dfs(int x){
    	for(int y, i = head[x]; i; i = nxt[i]){
    		y = ver[i];
    		if(y == fa[x]) continue;
    		fa[y] = x;
    		dfs(y);
    		lct[0].link(y);
    	}
    }
    signed main(){
    	n = read();
    	for(int x, y, i = 1; i < n; ++i){
    		x = read(), y = read();
    		add(x, y);
    		add(y, x);
    	}
    	dfs(1);
    	lct[0].prepro(n + 1);
    	lct[1].prepro(n + 1);
    	fa[1] = n + 1; lct[0].link(1);
    	m = read();
    	int op, x;
    	while(m--){
    		op = read(), x = read();
    		switch(op){
    			case 0:
    				printf("%d
    ", lct[col[x]].query(x));
    				break;
    			case 1 :
    				lct[col[x]].cut(x);
    				col[x] ^= 1;
    				lct[col[x]].link(x);
    		}
    	}
    				
    	return 0;
    }
    

    QTREE 7

    和 QTREE 6 一样, 还是开两颗 LCT

    只不过变成维护子树最值了, 用维护子树最值的方法就行了

    注意 (val in [-1e9, 1e9]) 所以 0 号点的 (maxi) 要取 (-inf)

    更改 (val) 时记着改两个树里的

    (code)

    #include<iostream>
    #include<cstdio>
    #include<cctype>
    #include<set>
    #include<cstring>
    using namespace std;
    #define rg register
    inline int read(){
    	rg char ch = getchar();
    	rg int x = 0, f = 0;
    	while(! isdigit(ch)) f |= (ch == '-'), ch = getchar();
    	while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();
    	return f ? -x : x;
    }	
    const int N = 1e5 + 5;
    int head[N], nxt[N << 1], ver[N << 1], tot;
    int fa[N], col[N];
    inline void add(int x, int y){
    	ver[++tot] = y;
    	nxt[tot] = head[x];
    	head[x] = tot;
    }
    #define inf 0x3f3f3f3f
    struct LCT{
    	int son[N][2], f[N], v[N], maxi[N];
    	multiset<int> s[N];
    	LCT(){ maxi[0] = -inf; }
    	inline int find(int p){
    		return s[p].empty() ? -inf : *s[p].rbegin();
    	}
    	#define ls son[p][0]
    	#define rs son[p][1]
    	#define fs(p) (son[f[p]][1] == p)
    	#define nroot(p) (son[f[p]][0] == p || son[f[p]][1] == p)
    	inline void up(int p){
    		maxi[p] = max(max(v[p], max(maxi[ls], maxi[rs])), find(p));
    	}
    	inline void ros(int p){
    		int fa = f[p], ffa = f[fa];
    		int c = fs(p);
    		if(nroot(fa)) son[ffa][fs(fa)] = p; f[p] = ffa;
    		son[fa][c] = son[p][c ^ 1]; f[son[p][c ^ 1]] = fa;
    		son[p][c ^ 1] = fa; f[fa] = p;
    		up(fa);
    	}
    	inline void splay(int p){
    		static int fa;
    		while(nroot(p)){
    			fa = f[p];
    			if(nroot(fa)) ros(fs(fa) ^ fs(p) ? p : fa);
    			ros(p);
    		}
    		up(p);
    	}
    	inline void access(int p){
    		for(int y = 0; p; p = f[y = p]){
    			splay(p);
    			if(rs) s[p].insert(maxi[rs]);
    			if(y) s[p].erase(s[p].find(maxi[y]));
    			rs = y;
    			up(p);
    		}
    	}
    	inline void link(int p){
    		access(p);
    		splay(p);
    		int pl = f[p] = fa[p];
    		access(pl);
    		splay(pl);
    		son[pl][1] = p;
    		up(pl);
    	}
    	inline void cut(int p){
    		access(p);
    		splay(p);
    		ls = f[ls] = 0;
    		up(p);
    	}
    	inline int findroot(int p){
    		access(p);
    		splay(p);
    		while(ls) p = ls;
    		splay(p);
    		return p;
    	}
    	inline int query(int p){
    		p = findroot(p);
    		return maxi[rs];
    	}
    	inline void change(int p, int val){
    		access(p);
    		splay(p);
    		v[p] = val;
    		up(p);
    	}
    }lct[2];
    void dfs(int x){
    	for(int y, i = head[x]; i; i = nxt[i]){
    		y = ver[i];
    		if(y == fa[x]) continue;
    		fa[y] = x;
    		lct[col[y]].link(y);
    		dfs(y);
    	}
    }
    int n, m;
    signed main(){
    	n = read();
    	for(int x, y, i = 1; i < n; ++i){
    		x = read(), y = read();
    		add(x, y);
    		add(y, x);
    	}
    	for(int i = 1; i <= n; ++i) col[i] = read();
    	for(int i = 1; i <= n; ++i) lct[0].maxi[i] = lct[0].v[i] = lct[1].maxi[i] = lct[1].v[i] = read();
    	dfs(1);
    	fa[1] = n + 1; lct[col[1]].link(1);
    	m = read();
    	int op, x, d;
    	while(m--){
    		op = read(), x = read();
    		switch(op){
    			case 0 : printf("%d
    ", lct[col[x]].query(x)); break;
    			case 1 : lct[col[x]].cut(x); lct[col[x] ^= 1].link(x); break;
    			case 2 : d = read(); lct[0].change(x, d), lct[1].change(x, d);
    		}
    	}
    	return 0;
    }
    

    完结撒花

  • 相关阅读:
    清除右键图形属性--图形选项
    Hibernate整合Struts2时报错
    shell基础篇(十)shell脚本的包含
    shell基础篇(九)函数
    浅谈sql的字符分割
    shell基础(八)-循环语句
    shell基础(七)-条件语句
    vue ---- Object的一些常用的方法
    vuex的应用和解决的实际问题
    webpack2代码分割
  • 原文地址:https://www.cnblogs.com/XiaoVsun/p/13054248.html
Copyright © 2011-2022 走看看