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}\) 的思路可以用到这道题上面,给每一条路径随机一个点权,维护出经过每一条边的点权的 \ ...
随机推荐
- inner join、left join、right join、full join
A表 a1 b1 c1 01 数学 95 02 语文 90 03 英语 80 B表 a2 b2 01 张三 02 李四 04 王五 SQL语句:select A.*,B.* from A inner ...
- 关于c语言的位运算&,|,^(看懂汉字的都能看懂)
其中|,&可以当作逻辑运算符,当|,&当成逻辑运算符时,与||,&&的用法基本相似,&&,||运算时会当前面的表达式能够决定整个表达式,则不进行对后面的 ...
- AdvancedEncryptionStandard
import java.security.GeneralSecurityException; import javax.crypto.Cipher; import javax.crypto.spec. ...
- web安全之文件上传漏洞攻击与防范方法
一. 文件上传漏洞与WebShell的关系 文件上传漏洞是指网络攻击者上传了一个可执行的文件到服务器并执行.这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等.这种攻击方式是最为直接和有效 ...
- java——二分搜索树 BST(递归、非递归)
~ package Date_pacage; import java.util.Stack; import java.util.ArrayList; import java.util.LinkedLi ...
- 爬虫(GET)——add_header()和get_header()
import urllib.request import random url = "http://www.baidu.com/" # 可以是User-Agent列表,也可以是代理 ...
- robotFramework 读取Excel文件
1.Robotframework读取Excel文件 第一步:先安装ExcelLibrary 可以直接通过命令安装:pip install robotframework-ExcelLibrary 安装完 ...
- python 基础内置函数表及简单介绍
内建函数名 (表达形式) 主要作用 备注 abs(x) 返回一个X值得绝对值(x=int/float/复数) all(iterable) 如果 iterable 的所有元素均为 True(或 iter ...
- inventor卸载不干净
AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...
- [转]JS判断访问设备、客户端操作系统类型
本文转自:http://www.cnblogs.com/duanguyuan/p/3534470.html 先给出一个实例:判断windows.linux.android 复制以下代码另存为html文 ...