求助 LCT 板子
查看原帖
求助 LCT 板子
463210
zzzYheng楼主2023/8/20 17:27

79pts,拍出错的数据都巨大,完全调不动。。。

#include <bits/stdc++.h>

using namespace std; 

struct LinkCutTree {
	struct Node {
		int ch[2]; 
		int fa; 
		int val; 
		int sum; 
		int rev_tag; 
	}; 
	
	vector<Node> tree; 
	
	map<pair<int, int>, bool> edge; 
	
	void init(int n, vector<int> &a) {
		tree.resize(n + 10); 
		for (int i = 1; i <= n; ++i) {
			tree[i].val = tree[i].sum = a[i]; 
			tree[i].ch[0] = tree[i].ch[1] = tree[i].fa = tree[i].rev_tag = 0; 
		}
	}
	
	void pushUp(int x) {
		tree[x].sum = tree[tree[x].ch[0]].sum ^ tree[tree[x].ch[1]].sum ^ tree[x].val;  
	}
	
	void pushDown(int x) {
		if (tree[x].rev_tag) {
			swap(tree[tree[x].ch[0]].ch[0], tree[tree[x].ch[0]].ch[1]); 
			tree[tree[x].ch[0]].rev_tag ^= 1; 
			swap(tree[tree[x].ch[1]].ch[0], tree[tree[x].ch[1]].ch[1]); 
			tree[tree[x].ch[1]].rev_tag ^= 1; 
			tree[x].rev_tag = 0; 
		}
	}
	
	int get(int x) { return tree[tree[x].fa].ch[1] == x; }
	
	int isRoot(int x) { return tree[tree[x].fa].ch[0] != x && tree[tree[x].fa].ch[1] != x; }
	
	void rotate(int x) {
      int y = tree[x].fa, z = tree[y].fa, t = get(x); 
      if (!isRoot(y)) tree[z].ch[get(y)] = x; 
      tree[y].ch[t] = tree[x].ch[t ^ 1], tree[tree[x].ch[t ^ 1]].fa = y; 
      tree[x].ch[t ^ 1] = y, tree[y].fa = x; 
      tree[x].fa = z; 
      pushUp(y), pushUp(x); 
   }
   
   void update(int x) {
      if (!isRoot(x)) update(tree[x].fa); 
      pushDown(x); 
   }
   
   void splay(int x) {
      update(x); 
      for (int fa = tree[x].fa; !isRoot(x); rotate(x), fa = tree[x].fa) {
         if (!isRoot(fa)) rotate(get(fa) == get(x) ? fa : x); 
      }
   }
   
   int access(int x) {
      splay(x); 
      tree[x].ch[1] = 0, pushUp(x); 
      while (tree[x].fa) {
         int fa = tree[x].fa; 
         splay(fa), tree[fa].ch[1] = x, pushUp(fa); 
         x = fa; 
      }
      return x; 
   }
   
   void makeRoot(int x) {
      access(x), splay(x); 
      swap(tree[x].ch[0], tree[x].ch[1]); 
      tree[x].rev_tag ^= 1; 
   }
   
   int findRoot(int x) {
      x = access(x); 
      pushDown(x); 
      while (tree[x].ch[0]) x = tree[x].ch[0], pushDown(x); 
      splay(x); 
      return x; 
   }
   
   void link(int x, int y) {
      if (findRoot(x) == findRoot(y)) return; 
      makeRoot(x), tree[x].fa = y; 
      edge[make_pair(x, y)] = edge[make_pair(y, x)] = 1; 
   }
   
   void cut(int x, int y) {
      if (!edge[make_pair(x, y)]) return; 
      makeRoot(x), access(x), tree[y].fa = 0; 
      edge[make_pair(x, y)] = edge[make_pair(y, x)] = 0; 
   }
   
   void updVal(int x, int y) {
      makeRoot(x), tree[x].val = y, pushUp(x); 
   }
   
   int split(int x, int y) {
      makeRoot(x); 
      return access(y); 
   }
} LCT; 

int main() {
	ios::sync_with_stdio(false); 
	cin.tie(0), cout.tie(0); 
	
	int n, m; 
	cin >> n >> m; 
	
	vector<int> a(n + 10); 
	for (int i = 1; i <= n; ++i) cin >> a[i]; 
	
	LCT.init(n, a); 
	
	while (m--) {
		int opt, x, y; 
		cin >> opt >> x >> y; 
		if (opt == 0) {
         cout << LCT.tree[LCT.split(x, y)].sum << '\n'; 
      }
      else if (opt == 1) {
         LCT.link(x, y); 
      }
      else if (opt == 2) {
         LCT.cut(x, y); 
      }
      else {
         LCT.updVal(x, y); 
      }
	} 
	return 0; 
}
2023/8/20 17:27
加载中...