UOJ #207. 共价大爷游长沙
#207. 共价大爷游长沙
题意:给一棵树,要求支持加边、删边、询问一条边是否被所有路径覆盖。同时路径端点集合有加入与删除操作。
想法:
考虑一个点与其父亲边是否被一条路径经过。
就是该路径的一端在其子树中,另一端不在。
就是其子树中一条路径的端点出现次数为奇数。随机给一条路径两端一个权值(错误概率为$\frac{n^2}{2^w}$),然后如果一个节点子树xor值等于当前路径xor值,其到父亲边就是可行的边。
然后便是LCT维护加边,删边,子树xor值。
Code $O(n \log n)$
#include < cstdio >
#include < cstdlib >
#include < ctime > #define gec getchar
#define FILE(F) freopen(F".in","r",stdin),freopen(F".out","w",stdout)
#define DEBUG fprintf(stderr,"Passing [%s] in Line (%d)\n",__FUNCTION__,__LINE__) typedef long long ll;
typedef unsigned long long ull;
template < typename T >
inline void read(T &x)
{
x=0;bool f=0; char c=gec();
for(;c<'0'||c>'9';c=gec())f=(c=='-');
for(;c>='0'&&c<='9';c=gec())x=x*10+c-'0';
x=f?-x:x;
} const int MAXN(100010),MAXM(300010);
int n,m,u,v,x,y,X[MAXM],Y[MAXM],tp;
ull QSQ,T[MAXM]; ull Random()
{
return rand()*1ull<<30|rand();;
} namespace Link_Cut_Tree
{
struct LCT
{
int nx[2],fa,rev;
ull val,sum,light;
//val:该节点xor值; sum:其子树xor值,light:其轻儿子xor值
}tr[MAXN]; void look(int x)
{
fprintf(stderr,"x%d\n",x);
fprintf(stderr,"nx[0]%d nx[1]%d fa%d\n",tr[x].nx[0],tr[x].nx[1],tr[x].fa);
} void swap(int &x,int &y){int t(x);x=y;y=t;}
int which(int x){if(tr[tr[x].fa].nx[0]==x)return 0;if(tr[tr[x].fa].nx[1]==x)return 1;return -1;} void update(int x)
{
tr[x].sum=tr[x].val^tr[x].light;
if(tr[x].nx[0])tr[x].sum^=tr[tr[x].nx[0]].sum;
if(tr[x].nx[1])tr[x].sum^=tr[tr[x].nx[1]].sum;
} void push(int x)
{
if(!tr[x].rev)return ;
swap(tr[x].nx[0],tr[x].nx[1]);
tr[tr[x].nx[0]].rev^=1;
tr[tr[x].nx[1]].rev^=1;
tr[x].rev=0;
} void rotate(int x)
{
int fa=tr[x].fa,fafa=tr[fa].fa,xd=which(x),fd=which(fa);
tr[tr[x].nx[xd^1]].fa=fa;
tr[fa].nx[xd]=tr[x].nx[xd^1];
tr[x].nx[xd^1]=fa;tr[fa].fa=x;
tr[x].fa=fafa;if(~fd)tr[fafa].nx[fd]=x;
update(fa);
} int st[MAXN],top;
void splay(int x)
{
st[top=1]=x;
for(int t=x;~which(t);t=tr[t].fa)st[++top]=tr[t].fa;
while(top)push(st[top--]);
while(~which(x))
{
int fa=tr[x].fa;
if(~which(fa)) rotate( which(x)^which(fa)? fa : x );
rotate(x);
}
update(x);
} void access(int x)
{
for(int t=0;x;t=x,x=tr[x].fa)
{
splay(x);
int Now=tr[x].nx[1];
if(Now)tr[x].light^=tr[Now].sum;
if(t )tr[x].light^=tr[t ].sum;
tr[x].nx[1]=t; update(x);
}
} void make_root(int x)
{
access(x); splay(x); tr[x].rev^=1;
} void link(int u,int v)
{
make_root(u); access(v); splay(v);
tr[u].fa=v; tr[v].light^=tr[u].sum; update(v);
} void cut(int u,int v)
{
make_root(u); access(v); splay(u);
tr[u].nx[1]=0; tr[v].fa=0; update(u);
} void Change(int x,ull D)
{
access(x); splay(x);
tr[x].val^=D; update(x);
} bool Que(int u,int v)
{
make_root(u); access(v); splay(u);
return tr[v].sum==QSQ;
} }using namespace Link_Cut_Tree; int main()
{
#ifndef ONLINE_JUDGE
FILE("C");
#endif
int id;read(id); srand(19260817);
read(n);read(m);
for(int i=1;i<n;i++)
{
read(u);read(v);
link(u,v);
}
for(int ty,i=1;i<=m;i++)
{
read(ty);
if(ty==1)
{
read(x);read(y); cut(x,y);
read(u);read(v); link(u,v);
}else
if(ty==2)
{
++tp;
read(X[tp]);read(Y[tp]);
T[tp]=Random();QSQ^=T[tp];
Change(X[tp],T[tp]); Change(Y[tp],T[tp]);
}else
if(ty==3)
{
read(x);QSQ^=T[x];
Change(X[x],T[x]); Change(Y[x],T[x]);
}else
{
read(x);read(y);
printf(Que(x,y)?"YES\n":"NO\n");
}
}
return 0;
}
UOJ #207. 共价大爷游长沙的更多相关文章
- UOJ #207. 共价大爷游长沙 [lct 异或]
#207. 共价大爷游长沙 题意:一棵树,支持加边删边,加入点对,删除点对,询问所有点对是否经过一条边 一开始一直想在边权上做文章,或者从连通分量角度考虑,比较接近正解了,但是没想到给点对分配权值所以 ...
- 【刷题】UOJ #207 共价大爷游长沙
火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编号为 \(1\) 到 ...
- [UOJ#207. 共价大爷游长沙]——LCT&随机化
题目大意: 传送门 给一颗动态树,给出一些路径并动态修改,每次询问一条边是否被所有路径覆盖. 题解: 先%一发myy. 开始感觉不是很可做的样子,发现子树信息无论维护什么都不太对…… 然后打开题目标签 ...
- UOJ #207. 共价大爷游长沙(LCT + 异或哈希)
题目 维护一颗动态树,并维护一个点对集合 \(S\) . 动态查询一条边,是否被集合中所有点对构成的路径包含. \(n \le 100000, m \le 300000\) 题解 orz 前辈 毛爷爷 ...
- 数据结构(动态树):UOJ 207 共价大爷游长沙
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABHwAAAJZCAIAAABUW7XHAAAgAElEQVR4nOy93cstx5Xm2f9TXh2EOe
- UOJ#207. 共价大爷游长沙 LCT
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ207.html 题解 第一次听说 LCT 还可以维护子树信息. 首先对于每一条路径 rand 一个值,分别 ...
- 【UOJ#207】共价大爷游长沙
题目链接 题目描述 火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编 ...
- 【UOJ207】共价大爷游长沙(Link-Cut Tree,随机化)
[UOJ207]共价大爷游长沙(Link-Cut Tree,随机化) 题面 UOJ 题解 这题太神了 \(\%\%\%myy\) 看到动态的维护边很容易的想到了\(LCT\) 然后能否堵住一条路 我们 ...
- 「UOJ207」共价大爷游长沙
「UOJ207」共价大爷游长沙 解题思路 : 快速判断两个集合是否完全相等可以随机点权 \(\text{xor}\) 的思路可以用到这道题上面,给每一条路径随机一个点权,维护出经过每一条边的点权的 \ ...
随机推荐
- PostgreSQL 存储过程/函数
1.有用的链接 postgresql 常用小函数 Postgresql数据库的一些字符串操作函数 PostgreSQL function里面调用function PostgreSQL学习手册(函数和操 ...
- Tomcat故障
1.1 故障日志 31-May-2018 16:11:41.136 INFO [http-nio-8017-exec-5] org.apache.coyote.http11.AbstractHttp1 ...
- web服务器Nginx环境下如何实现安全证书https的配置
https跟http的关系 https没出现之前,我们网站大多数都是http开头,http全名超文本传输协议,客户端据此获取服务器上的超文本内容.超文本内容则以HTML为主,客户端拿到HTML内容后可 ...
- 报错:The valid characters are defined in RFC 7230 and RFC 3986
访问 spring boot controller时,报错:The valid characters are defined in RFC 7230 and RFC 3986 1.特殊符号 @Spri ...
- Mybatis学习笔记9 - 鉴别器discriminator
鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装行为. 示例如下: DeptmentMapper接口定义: package com.mybatis.dao ...
- python 获取当前时间及前一天时间
import datetime from pandas.tseries.offsets import Day now_time =datetime.datetime.now()#获取当前时间 yes_ ...
- SETI ACdream - 1430 后缀自动机求不相交子串
http://blog.csdn.net/gatevin/article/details/45875343 题目是求不重叠的不同子串个数 一般来说, endpos集合包含了子串结尾位置,结尾在&quo ...
- verilog if语句
a.基本形式 1) if(表达式) 语句1: 2)if(表达式) 语句1: else 语句1 3) if(表达式1) 语句1: else if(表达式2) 语句2: else if(表达式3) ...
- DEDE模板中如何运行php脚本和php变量的使用
在使用dede模板的时候,经常会需要直接对dede数据库的底层字段进行处理,如果dede中没有相应的函数的时候,往往就需要我们想办法来处理了. 举例:我想取出数据表addonimages中的某一条记录 ...
- git 摘要
git使用摘记 git冲突的问题主要是在修改的部分而不是添加的部分, 如果merge的文件在同一个位置有不同的信息则git会报错 git push origin中的origin表示的是远程的仓库名为o ...