版权声明:xgc原创文章,未经允许不得转载。 https://blog.csdn.net/xgc_woker/article/details/80108314
Description
给定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。
Sample Input
3 3
1
2
3
1 1 2
0 1 2
0 1 1
Sample Output
3
1
这道题拿来练Link Cut Tree模版。。。
但,被Luogu的小数据Hank掉了,因为不保证(x,y)存在,比如这样一组数据:
5 6 1 2 3 4 5
1 1 2
1 2 3
1 3 4
1 4 5
2 1 5
0 1 5
好吧,那你就特判一下。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int _max(int x, int y) {return x > y ? x : y;}
struct node {
int f, s, d, lazy, son[2];
} t[310000];
int tp, temp[310000];
char ss[11];
void Lazy(int x) {
if(!t[x].lazy) return ;
t[x].lazy = 0;
swap(t[x].son[0], t[x].son[1]);
int lc = t[x].son[0], rc = t[x].son[1];
if(lc) t[lc].lazy ^= 1;
if(rc) t[rc].lazy ^= 1;
}
void update(int x) {
int lc = t[x].son[0], rc = t[x].son[1];
t[x].s = t[x].d ^ t[lc].s ^ t[rc].s;
}
void rotate(int x, int fx) {
int f = t[x].f, ff = t[f].f;
int r, R;
r = t[x].son[fx], R = f;
if(r) t[r].f = R;
t[R].son[1 ^ fx] = r;
r = x, R = ff;
t[r].f = R;
if(t[ff].son[0] == f) t[R].son[0] = r; else if(t[ff].son[1] == f) t[R].son[1] = r;
r = f, R = x;
t[r].f = R;
t[R].son[fx] = r;
update(f);
update(x);
}
bool hh(int x) {
int f = t[x].f;
if(f == 0 || (t[f].son[0] != x && t[f].son[1] != x)) return 0;
return 1;
}
void splay(int x) {
int i = x; tp = 0;
while(hh(i)) temp[++tp] = i, i = t[i].f;
temp[++tp] = i;
for(int i = tp; i >= 1; i--) Lazy(temp[i]);
while(hh(x)) {
int f = t[x].f, ff = t[f].f;
if(!hh(f)) {
if(t[f].son[0] == x) rotate(x, 1);
else rotate(x, 0);
}
else if(t[ff].son[0] == f && t[f].son[0] == x) rotate(f, 1), rotate(x, 1);
else if(t[ff].son[0] == f && t[f].son[1] == x) rotate(x, 0), rotate(x, 1);
else if(t[ff].son[1] == f && t[f].son[1] == x) rotate(f, 0), rotate(x, 0);
else if(t[ff].son[1] == f && t[f].son[0] == x) rotate(x, 1), rotate(x, 0);
}
}
void Access(int x) {
int y = 0;
while(x) {
splay(x);
t[x].son[1] = y;
if(y) t[y].f = x;
update(x);
y = x; x = t[x].f;
}
}
void Makert(int x) {
Access(x); splay(x);
t[x].lazy ^= 1;
}
void Link(int x, int y) {
Makert(x); t[x].f = y; Access(x);
}
void Cut(int x, int y) {
Makert(x);
Access(y); splay(y);
if(t[y].son[0] != x || (t[y].son[0] == x && t[x].son[1])) return ;
t[t[y].son[0]].f = 0; t[y].son[0] = 0;
update(y);
}
int Findrt(int x) {
Access(x); splay(x);
while(t[x].son[0]) x = t[x].son[0];
return x;
}
int finds(int x, int y) {
Makert(x);
Access(y); splay(y);
return t[y].s;
}
int main() {
int n, m; scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) {
int x; scanf("%d", &x);
t[i].d = t[i].s = x;
}
for(int i = 1; i <= m; i++) {
int opt; scanf("%d", &opt);
int x, y; scanf("%d%d", &x, &y);
if(opt == 0) printf("%d\n", finds(x, y));
else if(opt == 1) Link(x, y);
else if(opt == 2) {
if(Findrt(x) == Findrt(y)) Cut(x, y);
}
else {
Makert(x);
t[x].d = y;
update(x);
}
}
return 0;
}