博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LCT入门
阅读量:4664 次
发布时间:2019-06-09

本文共 2606 字,大约阅读时间需要 8 分钟。

什么都不想写了,

看大佬们的博客吧QAQ

题目背景

动态树

题目描述

给定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。

输入格式

第1行两个整数,分别为n和m,代表点数和操作数。

第2行到第n+1行,每行一个整数,整数在[1,10^9]内,代表每个点的权值。

第n+2行到第n+m+1行,每行三个整数,分别代表操作类型和操作所需的量。

输出格式

对于每一个0号操作,你须输出x到y的路径上点权的xor和。

输入输出样例

putin

3 3 1231 1 20 1 2 0 1 1

putout

1

#include
#define re return#define ls c[x][0]#define rs c[x][1] #define Ri register int#define inc(i,l,r) for(int i=l;i<=r;++i)const int maxn=3e5+5;using namespace std;template
inline void rd(T&x){ char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1l; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x;}int q[maxn],n,m,c[maxn][2],val[maxn],ans[maxn],f[maxn];bool rev[maxn];inline bool nrt(int x){ re c[f[x]][0]==x||c[f[x]][1]==x;}inline void pushup(int x){ ans[x]=ans[ls]^ans[rs]^val[x];}inline void filp(int x){ rev[x]^=1; swap(ls,rs);}inline void pushrev(int x){ if(!rev[x])re; rev[x]=0; if(ls)filp(ls); if(rs)filp(rs);}inline void rotate(int x){ int y=f[x],z=f[y],k=(c[y][1]==x),w=c[x][!k]; if(nrt(y))c[z][c[z][1]==y]=x;c[x][!k]=y;c[y][k]=w; if(w)f[w]=y;f[x]=z;f[y]=x; pushup(y),pushup(x);}inline void splay(int x){ int y=x,top=0;q[++top]=y; while(nrt(y))q[++top]=y=f[y]; while(top)pushrev(q[top--]); while(nrt(x)) { y=f[x],top=f[y]; if(nrt(y)) ((c[y][0]==x)&&(c[top][0]==y))?rotate(y):rotate(x); rotate(x); } //pushup(x)}inline void Access(int x)//将x->rt改为实边 { for(Ri y=0;x;x=f[y=x]) { splay(x); c[x][1]=y; pushup(x); }}inline void makert(int x)//使rt变为rt { Access(x);splay(x); filp(x);//降低复杂度 }inline int findrt(int x)//寻找根节点 { Access(x);splay(x); while(ls)pushrev(x),x=ls; re x;}inline void split(int x,int y)//将x,y弄到同一棵splay { makert(x);Access(y);splay(y);}inline void link(int x,int y){ makert(x); if(findrt(y)!=x)f[x]=y; }inline void cut(int x,int y){ split(x,y); if(findrt(y)!=x||f[x]!=y||rs) re; else { f[x]=c[y][0]=0; pushup(y); }}int main(){ int opt,x,y; rd(n),rd(m); inc(i,1,n)rd(val[i]); inc(i,1,m) { rd(opt);rd(x),rd(y); switch(opt){ case 0:split(x,y);printf("%d\n",ans[y]);break; case 1:link(x,y);break; case 2:cut(x,y);break; case 3:splay(x);val[x]=y;break; } } re 0;}

 

转载于:https://www.cnblogs.com/lsyyy/p/11298459.html

你可能感兴趣的文章
JSP介绍(2)--- 九大隐式对象
查看>>
[置顶] .net技术类面试、笔试题汇总3
查看>>
JAVA操作Hbase基础例子
查看>>
js表达式和语句趣味题讲解与技术分享
查看>>
【VC++技术杂谈006】截取电脑桌面并将其保存为bmp图片
查看>>
Java多线程编程(五)定时器Timer
查看>>
如何正确使用const(常量),define(宏)
查看>>
Linux系统目录权限chmod误操作权限修复方法
查看>>
wp7中如和从app.xaml.cs中直接导航到程序的某个页面
查看>>
Eclipse Jee Neon打开时报错 code=13的问题
查看>>
pymysql
查看>>
restframework之序列化
查看>>
配置网卡
查看>>
使用Asp.net mvc + Linq + mvc_scaffold_gen_setup.exe 生成一个完整的家庭帐册大管家程序 之二...
查看>>
利用URL重写隐藏复杂的URL
查看>>
支持二次开发的Zigbee模块(SNAP技术)
查看>>
Confluence 6 生产环境备份策略
查看>>
springmvc.xml配置
查看>>
C primer plus 学习随笔(1)
查看>>
Java 哈希表运用-LeetCode 1 Two Sum
查看>>