bzoj3282 tree
来源:互联网 发布:淘宝店免费代理货源 编辑:程序博客网 时间:2024/06/15 13:56
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。
Input
第1行两个整数,分别为N和M,代表点数和操作数。
第2行到第N+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。
第N+2行到第N+M+1行,每行三个整数,分别代表操作类型和操作所需的量。
Output
对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。
Sample Input
3 3
1
2
3
1 1 2
0 1 2
0 1 1
1
2
3
1 1 2
0 1 2
0 1 1
Sample Output
3
1
1
HINT
1<=N,M<=300000
Source
动态树
分析:
LCT的经典操作
看来LCT不仅能解决路径权值和,还可以维护路径异或和
//这里写代码片#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int N=300010;int n,m,v[N],sum[N],ch[N][2],pre[N],q[N];bool rev[N];int get(int bh){ return ch[pre[bh]][0]==bh? 0:1;}int isroot(int bh){ return ch[pre[bh]][0]!=bh&&ch[pre[bh]][1]!=bh;}void update(int bh){ if (!bh) return; sum[bh]=v[bh]; if (ch[bh][0]) sum[bh]^=sum[ch[bh][0]]; if (ch[bh][1]) sum[bh]^=sum[ch[bh][1]];}void push(int bh){ if (!bh) return; if (rev[bh]) { if (ch[bh][0]) rev[ch[bh][0]]^=1; if (ch[bh][1]) rev[ch[bh][1]]^=1; swap(ch[bh][0],ch[bh][1]); rev[bh]^=1; }}void rotate(int bh){ int fa=pre[bh]; int grand=pre[fa]; int wh=get(bh); if (!isroot(fa)) ch[grand][ch[grand][0]==fa? 0:1]=bh; pre[bh]=grand; ch[fa][wh]=ch[bh][wh^1]; pre[ch[fa][wh]]=fa; ch[bh][wh^1]=fa; pre[fa]=bh; update(fa); update(bh);}void splay(int bh){ int top=0; q[++top]=bh; for (int i=bh;!isroot(i);i=pre[i]) q[++top]=pre[i]; while (top) push(q[top--]); for (int fa;!isroot(bh);rotate(bh)) if (!isroot(fa=pre[bh])) rotate(get(fa)==get(bh)? fa:bh);}void expose(int bh){ int t=0; while (bh) { splay(bh); ch[bh][1]=t; update(bh); t=bh; bh=pre[bh]; }}void makeroot(int bh){ expose(bh); splay(bh); rev[bh]^=1;}void link(int x,int y){ makeroot(x); pre[x]=y;}void cut(int x,int y){ makeroot(x); expose(y); splay(y); pre[x]=ch[y][0]=0;}int find(int x){ expose(x); splay(x); while (ch[x][0]) x=ch[x][0]; return x;}int asksum(int x,int y){ makeroot(x); expose(y); splay(y); return sum[y];}void change(int x,int z){ makeroot(x); v[x]=z; update(x);}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%d",&v[i]),sum[i]=v[i]; for (int i=1;i<=m;i++) { int opt,x,y; scanf("%d%d%d",&opt,&x,&y); if (opt==0) printf("%d\n",asksum(x,y)); else if (opt==1){ if (find(x)!=find(y)) link(x,y); } else if (opt==2) { if (find(x)==find(y)) cut(x,y); } else { change(x,y); } } return 0;}
阅读全文
0 0
- bzoj3282: Tree
- 【BZOJ3282】Tree
- [BZOJ3282] Tree
- 【bzoj3282】Tree
- BZOJ3282: Tree
- bzoj3282 tree
- 【bzoj3282】Tree LCT
- 【bzoj3282】【Tree】【lct】
- [BZOJ3282]Tree(LCT)
- [bzoj3282]tree 解题报告
- BZOJ3282——Tree
- [BZOJ3282][LCT]Tree
- 【bzoj3282】Tree LCT
- 【BZOJ3282】Tree【Link-Cut Tree】
- [bzoj3282]Tree Link-Cut-Tree
- 【BZOJ3282】Tree (Link-Cut Tree)
- [BZOJ3282/LGOJ3690] Link-Cut Tree 模板题
- BZOJ3282【LCT】
- JavaWeb-Maven Profile 切换注册中心连接配置
- 数独的Java版解法
- QMenu上设置Icon遇到的问题(一)
- 矩阵求导公式
- 论dubbo版本升级的重要性【spring boot +dubbo】
- bzoj3282 tree
- Druid 介绍及配置
- 动态内存函数
- vmware12及vmware14注册码
- IOS系统
- SSM+EasyUI分页脚本简用
- 内核启动1-启动流程总述/bootlader学习
- AndroidStudio低版本sdkversion开发 Error:Minimum supported Gradle version is 4.1 Current version is 2.14.1
- Spark (一)