BZOJ_3282_Tree_LCT
BZOJ_3282_Tree_LCT
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行,每行三个整数,分别代表操作类型和操作所需的量。
1<=N,M<=300000
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
LCT维护一下点权的xor和,单点修改直接暴力。
修改的时候应该是不用access,但我加上access操作会快一些
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define N 300050 #define ls ch[p][0] #define rs ch[p][1] #define get(x) (ch[f[x]][1]==x) int ch[N][2],f[N],sum[N],n,m,val[N],rev[N]; inline bool isrt( int p) { return ch[f[p]][1]!=p&&ch[f[p]][0]!=p; } inline void pushdown( int p) { if (rev[p]) { swap(ch[ls][0],ch[ls][1]); swap(ch[rs][0],ch[rs][1]); rev[ls]^=1; rev[rs]^=1; rev[p]=0; } } inline void pushup( int p) { sum[p]=sum[ls]^sum[rs]^val[p]; } inline void update( int p) { if (!isrt(p)) update(f[p]); pushdown(p); } void rotate( int x) { int y=f[x],z=f[y],k=get(x); if (!isrt(y)) ch[z][ch[z][1]==y]=x; ch[y][k]=ch[x][!k]; f[ch[y][k]]=y; ch[x][!k]=y; f[y]=x; f[x]=z; pushup(y); pushup(x); } void splay( int x) { update(x); for ( int fa;fa=f[x],!isrt(x);rotate(x)) if (!isrt(fa)) rotate(get(fa)==get(x)?fa:x); } void access( int p) { int t=0; while (p) splay(p),rs=t,pushup(p),t=p,p=f[p]; } void makeroot( int p) { access(p); splay(p); swap(ls,rs); rev[p]^=1; } void link( int x, int p) { makeroot(x); f[x]=p; } void cut( int x, int p) { makeroot(x); access(p); splay(p); ls=f[x]=0; } int find( int p) { access(p); splay(p); while (ls) pushdown(p),p=ls; return p; } void fix( int x, int v) { /*access(x);*/ splay(x); sum[x]^=val[x]; val[x]=v; sum[x]^=val[x]; } int main() { scanf ( "%d%d" ,&n,&m); int i,x,y,opt; for (i=1;i<=n;i++) scanf ( "%d" ,&val[i]); for (i=1;i<=m;i++) { scanf ( "%d%d%d" ,&opt,&x,&y); if (opt==0) { makeroot(x); access(y); splay(y); printf ( "%d\n" ,sum[y]); } else if (opt==1) { int t1=find(x),t2=find(y); if (t1!=t2) link(x,y); } else if (opt==2) { int t1=find(x),t2=find(y); if (t1==t2) cut(x,y); } else { fix(x,y); } } } |
标签:
LCT
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(四):结合BotSharp
· 一个基于 .NET 开源免费的异地组网和内网穿透工具
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单