话说我可能还没有调出魔法森林呢。。。说好的lct第一题呢。。。

又是一个随机化的方法,毕竟又是判定性的问题

上次是判断无向图联通

这次是判断一些路径是否经过一条定边

若把路径上的边全部异或上一个路径的权值

只要判断这条边的权值是否是所有路径的权值异或和就没了

lct维护链上异或和就好了

 #include<bits/stdc++.h>
#define MAXN 100010
#define MAXM 300010
#define ll long long
using namespace std;
int fa[MAXN],son[MAXN][],siz[MAXN],pe[MAXN],ne[MAXN],fe[MAXN],le[MAXN],sum[MAXN],ch[MAXN];
int val[MAXN+MAXM];
bool rev[MAXN];
int st[MAXN],tp;
int v[MAXM],v1[MAXM],v2[MAXM],cnt;
int n,m;
int S;
int tot;
int rd()
{
if(RAND_MAX==) return (rand()<<)+rand();
else return rand();
}
bool ir(int x)
{
return son[fa[x]][]!=x&&son[fa[x]][]!=x;
}
void ud(int x)
{
siz[x]=siz[son[x][]]+siz[son[x][]]+;
sum[x]=;
fe[x]=pe[x];
le[x]=ne[x];
if(son[x][])
{
sum[x]^=sum[son[x][]]^val[pe[x]];
fe[x]=fe[son[x][]];
}
if(son[x][])
{
sum[x]^=sum[son[x][]]^val[ne[x]];
le[x]=le[son[x][]];
}
}
void torev(int x)
{
if(!x)
return;
swap(son[x][],son[x][]);
swap(pe[x],ne[x]);
swap(fe[x],le[x]);
rev[x]^=;
}
void toch(int x,int y)
{
if(!x)
return;
if(siz[x]&^)
sum[x]^=y;
if(son[x][])
val[pe[x]]^=y;
if(son[x][])
val[ne[x]]^=y;
ch[x]^=y;
}
void pd(int x)
{
if(rev[x])
{
torev(son[x][]);
torev(son[x][]);
rev[x]=;
}
if(ch[x])
{
toch(son[x][],ch[x]);
toch(son[x][],ch[x]);
ch[x]=;
}
}
void cot(int x,int y,int z)
{
if(x)
fa[x]=y;
if(y)
son[y][z]=x;
}
void rot(int x,bool z)
{
int xx=fa[x],xxx=fa[xx];
cot(son[x][z],xx,z^);
if(ir(xx))
fa[x]=xxx;
else
cot(x,xxx,son[xxx][]==xx);
cot(xx,x,z);
ud(xx);
}
void apd(int x)
{
int i;
st[++tp]=x;
for(i=x;!ir(i);i=fa[i])
st[++tp]=fa[i];
for(;tp;tp--)
pd(st[tp]);
}
void splay(int x)
{
apd(x);
while(!ir(x))
{
int xx=fa[x],xxx=fa[xx];
if(ir(xx))
rot(x,son[xx][]==x);
else
{
bool z=son[xxx][]==xx;
if(son[xx][z]==x)
{
rot(x,z^);
rot(x,z);
}
else
{
rot(xx,z);
rot(x,z);
}
}
}
ud(x);
}
void acs(int x)
{
int t=;
while(x)
{
splay(x);
son[x][]=t;
ne[x]=fe[t];
ud(x);
t=x;
x=fa[x];
}
}
void reboot(int x)
{
acs(x);
splay(x);
torev(x);
}
void link(int x,int y,int z)
{
reboot(x);
fa[x]=y;
pe[x]=z;
}
void pick(int x,int y)
{
reboot(y);
acs(x);
splay(x);
}
void cut(int x,int y)
{
pick(x,y);
son[x][]=fa[y]=;
pe[x]=fe[x]=ne[y]=le[y]=;
ud(x);
ud(y);
}
int ask(int x,int y)
{
pick(x,y);
return sum[x];
}
void change(int x,int y,int z)
{
pick(x,y);
toch(x,z);
}
int main()
{
int i,o,x,y,z,xx,yy;
srand(time());
scanf("%*d%d%d",&n,&m);
for(i=;i<=n;i++)
siz[i]=;
for(i=;i<n;i++)
{
scanf("%d%d",&x,&y);
link(x,y,++tot);
}
while(m--)
{
int cmd;
scanf("%d",&cmd);
if(cmd==)
{
scanf("%d%d%d%d",&x,&y,&xx,&yy);
z=ask(x,y);
cut(x,y);
link(xx,yy,++tot);
change(x,y,z);
}
if(cmd==)
{
cnt++;
scanf("%d%d",&v1[cnt],&v2[cnt]);
v[cnt]=rd();
S^=v[cnt];
change(v1[cnt],v2[cnt],v[cnt]);
}
if(cmd==)
scanf("%d",&x),
S^=v[x],
change(v1[x],v2[x],v[x]);
if(cmd==)
scanf("%d%d",&x,&y),
puts(ask(x,y)==S?"YES":"NO");
}
return ;
}

最新文章

  1. python常见数据类型
  2. 将一个Asp.Net网站改为MVC
  3. Linux默认权限的计算公式(个人理解性的笔记~)
  4. Netsharp快速入门(之6) 基础档案(创建导航菜单)
  5. 让Fragment监听返回键
  6. MYSQL常用命令集合(转载)
  7. 直接修改别人jar包里面的class文件 工具:jclasslib
  8. StringBuilder[] 作为数组如何使用
  9. &quot;《算法导论》之‘排序’&quot;:线性时间排序
  10. bugku crypto 告诉你一个秘密(ISCCCTF)
  11. W10激活
  12. HIT2019春软件构造-&gt;Git&amp;Github学习笔记
  13. Spring Security之动态配置资源权限
  14. 虚拟机中操作系统的克隆方法及ip修改及硬件地址修改
  15. java的Io流学习
  16. 【BZOJ2227】[ZJOI2011]看电影(组合数学,高精度)
  17. STM32F103ZET6 之 ADC+TIM+DMA+USART 综合实验
  18. Tp3.2 复合查询
  19. easy.py使用中ValueError: could not convert string to float: svm_options错误问题解决
  20. ASP.NET Core网站初探

热门文章

  1. Mac系统存储-其他存储无故增大
  2. 分享知识-快乐自己:IDEA 导入(web)项目并部署到 Tomcat
  3. NOIP 2016【蚯蚓】
  4. Unity 摄像机旋转初探
  5. leetcode 307. Range Sum Query - Mutable(树状数组)
  6. 每天一个Linux命令(2):ls命令
  7. ***静态成员的定义及初始化 for c++ for新用法
  8. 「LOJ#10042」「一本通 2.1 练习 8」收集雪花 (map
  9. MongoDB4.0.0的安装配置—windows
  10. hdu3037Saving Beans——卢卡斯定理