[BZOJ3282][tree][LCT]
2017-03-29 18:53
295 查看
[BZOJ3282][tree][LCT]
题目大意:
给定N个点以及每个点的权值,要你处理接下来的M个操作。操作有4种。操作从0到3编号。点从1到N编号。0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。保证x到y是联通的。
1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
3:后接两个整数(x,y),代表将点X上的权值变成Y。
思路:
LCT裸题???维护一下子树的xor和就好了。
代码:
#include <bits/stdc++.h> using namespace std; const int Maxn = 300005; inline char get(void) { static char buf[100000], *p1 = buf, *p2 = buf; if (p1 == p2) { p2 = (p1 = buf) + fread(buf, 1, 100000, stdin); if (p1 == p2) return EOF; } return *p1++; } inline void read(int &x) { x = 0; static char c; for (; !(c >= '0' && c <= '9'); c = get()); for (; c >= '0' && c <= '9'; x = x * 10 + c - '0', c = get()); } int c[Maxn][2], fa[Maxn], rev[Maxn], s[Maxn], v[Maxn], st[Maxn], top; inline void pushUp(int x) { int l = c[x][0], r = c[x][1]; s[x] = s[l] ^ s[r] ^ v[x]; } inline void pushDown(int x) { int &l = c[x][0], &r = c[x][1]; if (rev[x]) { rev[l] ^= 1; rev[r] ^= 1; rev[x] ^= 1; swap(l, r); } } inline bool Rt(int x) { return c[fa[x]][0] != x && c[fa[x]][1] != x; } inline void rotate(int x) { int y = fa[x], z = fa[y], l = (c[y][1] == x), r = l ^ 1; if (!Rt(y)) { if (c[z][0] == y) c[z][0] = x; else c[z][1] = x; } fa[x] = z; fa[y] = x; fa[c[x][r]] = y; c[y][l] = c[x][r]; c[x][r] = y; pushUp(y), pushUp(x); } inline void splay(int x) { st[++top] = x; for (int i = x; !Rt(i); i = fa[i]) st[++top] = fa[i]; while (top) pushDown(st[top--]); while (!Rt(x)) { int y = fa[x], z = fa[y]; if (!Rt(y)) { if ((c[y][0] == x) ^ (c[z][0] == y)) rotate(x); else rotate(y); } rotate(x); } } inline void access(int x) { for (int t = 0; x; t = x, x = fa[x]) splay(x), c[x][1] = t, pushUp(x); } inline void makeroot(int x) { access(x), splay(x), rev[x] ^= 1; } inline void link(int x, int y) { makeroot(x), fa[x] = y; } inline void cut(int x, int y) { makeroot(x); access(y), splay(y); if (c[y][0] == x) c[y][0] = fa[x] = 0; } inline int find(int x) { access(x), splay(x); while (c[x][0]) x = c[x][0]; return x; } int n, m; int main(void) { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); read(n), read(m); for (int i = 1; i <= n; i++) read(s[i]), v[i] = s[i]; int op, x, y; for (int i = 1; i <= m; i++) { read(op), read(x), read(y); if (op == 0) { makeroot(x), access(y), splay(y); printf("%d\n", s[y]); } else if (op == 1) { if (find(x) != find(y)) link(x, y); } else if (op == 2) { if (find(x) == find(y)) cut(x, y); } else { access(x); splay(x); v[x]=y; pushUp(x); } } return 0; }
完。
By g1n0st
相关文章推荐
- 【BZOJ】3282: Tree(lct)
- BZOJ 3282 Tree Link-Cut-Tree(LCT)
- [bzoj3282]Tree_LCT
- BZOJ_3282_Tree_(LCT)
- BZOJ_3282_Tree_LCT
- 【bzoj3282】Tree LCT
- [BZOJ3282]Tree(LCT)
- [BZOJ3282][LCT]Tree
- [bzoj3282]Tree (lct)
- BZOJ 3282 Tree Link-Cut-Tree(LCT)
- BZOJ 3282: Tree [LCT]
- [BZOJ 3282] Tree 【LCT】
- BZOJ 3282: Tree (LCT)题解
- BZOJ 3282: Tree( LCT )
- 【bzoj3282】【Tree】【lct】
- [BZOJ]3282: Tree lct
- [BZOJ3282]Tree(LCT)
- [BZOJ3282]Tree
- bzoj 3282 Tree 动态树LCT
- 【lct模板】bzoj2631: tree