题目链接

题目描述

火车司机出秦川,跳蚤国王下江南,共价大爷游长沙。每个周末,勤劳的共价大爷都会开车游历长沙市。

长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编号为 \(1\) 到 \(n\),任意两点间均存在恰好一条路径,显然两个点之间最多也只会有一条边相连。有一个包含一些点对 \((x,y)\) 的可重集合\(S\),共价大爷的旅行路线是这样确定的:每次他会选择 \(S\) 中的某一对点 \((x,y)\),并从 \(x\) 出发沿着唯一路径到达 \(y\)。

小L是共价大爷的脑残粉,为了见到共价大爷的尊容,小L决定守在这张图的某条边上等待共价大爷的到来。为了保证一定能见到他,显然小L必须选择共价大爷一定会经过的边——也就是所有共价大爷可能选择的路径都经过的边。

现在小L想知道,如果他守在某一条边,是否一定能见到共价大爷。

然而长沙市总是不断的施工,也就是说,可能某个时刻某条边会断开,同时这个时刻一定也有某条新边会出现,且任意时刻图都满足任意两点间均存在恰好一条路径的条件。注意断开的边有可能和加入的新边连接着相同的两个端点。共价大爷的兴趣也会不断变化,所以S也会不断加入新点对或者删除原有的点对。当然,小L也有可能在任何时候向你提出守在某一条边是否一定能见到共价大爷的问题。你能回答小L的所有问题吗?

Sol

动态加删边用 \(LCT\)

考虑如何处理路径交。

一种方法是直接对链做一次覆盖。交必须满足被覆盖的次数为当前总的 \(S\) 集合大小

但是这种做法当我们删掉一条链上的边的时候 , 它必须要一个个把贡献去掉并且重新覆盖 , 显然是不行的。

我们要支持能够快速删除与当前边相关的所有路径覆盖操作的方法。

异或操作是支持快速撤销的 , 只需要再次异或一次就行了。

我们每次加入一条路径的时候给他随机一个权值 , 然后用这个权值去覆盖。

删除一条边时 , 我们能够直接知道这条边上的权值的异或和 , 用这个值重新覆盖一次新的路径即可,稍微画一下图就知道这个做法是对的了。这样做就要用 \(LCT\) 维护边权,不是那么好写。

另一种做法。

当我们询问一条边\((u,v)\)的时候 , 如果满足条件 , 必定是所有路径的一端在以 \(v\) 为根 \(u\) 的子树里 , 另一端在以 \(u\) 为根 \(v\) 的子树里 , 我们只需要判断一边就可以了。

于是还是给每一条路径随机一个权值 ,然后修改端点的权值。

于是只需要查询以\(u\)为根 \(v\) 的子树和是否和全局的一半一致即可。

code:

#include<bits/stdc++.h>
using namespace std;
template<class T>inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;return;
}
const int N=1e5+10;
int ID;
#define ls son[0]
#define rs son[1]
#define get_son(a) (a->fa->rs==a)
#define IS(a) ((a)&&((!(a->fa))||(a->fa->ls!=a&&a->fa->rs!=a)))
#define get_S(a) (a? a->S:0)
const int INF=1e9;
#define __ NULL
typedef long long ll;
struct node{
node *son[2],*fa;int val,S;bool rev;
node(){ls=rs=fa=__,S=val=rev=0;}
}T[N];
node* st[N];int top=0;
int n,m;
inline void update(node*p){if(!p) return;p->S=get_S(p->ls)^get_S(p->rs)^p->val;return;}
inline void push_down(node*p){
if(!p||!p->rev) return;
swap(p->ls,p->rs);
if(p->ls) p->ls->rev^=1;
if(p->rs) p->rs->rev^=1;
p->rev=0;
return;
}
inline void Push(node*p){top=0;
while(!IS(p)) st[++top]=p,p=p->fa;
push_down(p);while(top) push_down(st[top]),st[top--]=__;
}
inline void rotate(node*p){if(!p) return;
int k=get_son(p);node *q=p->fa,*gp=p->fa->fa;
q->son[k]=p->son[k^1];
if(p->son[k^1]) p->son[k^1]->fa=q;
if(!IS(q)) gp->son[get_son(q)]=p;
p->fa=gp;q->fa=p;p->son[k^1]=q;
return update(q);
}
inline void Splay(node*p){
if(!p) return;Push(p);
for(;!IS(p);rotate(p)) if(IS(p->fa)) continue;else (get_son(p->fa)==get_son(p)? rotate(p->fa):rotate(p));
return update(p);
}
int U[N*3],V[N*3],tot=0,val[N*3];
inline void access(node*p) {
node*pre=__;
for(;p;pre=p,p=p->fa) {Splay(p);p->val^=get_S(p->rs)^(get_S(pre));p->rs=pre;update(p);}
return;
}
inline void make_root(node*p){access(p);Splay(p);p->rev^=1;}
inline void split(node*p,node*q){make_root(p),access(q),Splay(q);};
inline void Link(node*p,node*q){split(p,q);p->fa=q;q->val^=p->S;update(q);}
inline void Cut(node*p,node*q){split(p,q);if(q->ls==p) p->fa=q->ls=__,update(q);}
int Sum=0;
int main()
{
srand(time(NULL));
init(ID);init(n),init(m);
int u,v;
for(int i=1;i<n;++i) {init(u),init(v);Link(&T[u],&T[v]);}
for(int i=1;i<=m;++i) {
int tp;
init(tp);
if(tp==1) {
int x,y;
init(x),init(y),init(u),init(v);
Cut(&T[x],&T[y]);
Link(&T[u],&T[v]);
}else if(tp==2) {
++tot;init(U[tot]),init(V[tot]);
val[tot]=(ll)rand()*rand()%INF;
Sum^=val[tot];
make_root(&T[U[tot]]);
T[U[tot]].val^=val[tot];T[U[tot]].S^=val[tot];
make_root(&T[V[tot]]);
T[V[tot]].val^=val[tot];T[V[tot]].S^=val[tot];
}else if(tp==3) {
int x;init(x);
Sum^=val[x];
make_root(&T[U[x]]);
T[U[x]].val^=val[x];T[U[x]].S^=val[x];
make_root(&T[V[x]]);
T[V[x]].val^=val[x];T[V[x]].S^=val[x];
}
else {
int x,y;init(x),init(y);
split(&T[x],&T[y]);
if(T[x].S==Sum) puts("YES");else puts("NO");
} }
}

【UOJ#207】共价大爷游长沙的更多相关文章

  1. UOJ #207. 共价大爷游长沙

    #207. 共价大爷游长沙 链接:http://uoj.ac/problem/207 题意:给一棵树,要求支持加边.删边.询问一条边是否被所有路径覆盖.同时路径端点集合有加入与删除操作. 想法: 考虑 ...

  2. UOJ #207. 共价大爷游长沙 [lct 异或]

    #207. 共价大爷游长沙 题意:一棵树,支持加边删边,加入点对,删除点对,询问所有点对是否经过一条边 一开始一直想在边权上做文章,或者从连通分量角度考虑,比较接近正解了,但是没想到给点对分配权值所以 ...

  3. 【刷题】UOJ #207 共价大爷游长沙

    火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编号为 \(1\) 到 ...

  4. [UOJ#207. 共价大爷游长沙]——LCT&随机化

    题目大意: 传送门 给一颗动态树,给出一些路径并动态修改,每次询问一条边是否被所有路径覆盖. 题解: 先%一发myy. 开始感觉不是很可做的样子,发现子树信息无论维护什么都不太对…… 然后打开题目标签 ...

  5. UOJ #207. 共价大爷游长沙(LCT + 异或哈希)

    题目 维护一颗动态树,并维护一个点对集合 \(S\) . 动态查询一条边,是否被集合中所有点对构成的路径包含. \(n \le 100000, m \le 300000\) 题解 orz 前辈 毛爷爷 ...

  6. 数据结构(动态树):UOJ 207 共价大爷游长沙

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABHwAAAJZCAIAAABUW7XHAAAgAElEQVR4nOy93cstx5Xm2f9TXh2EOe

  7. UOJ#207. 共价大爷游长沙 LCT

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ207.html 题解 第一次听说 LCT 还可以维护子树信息. 首先对于每一条路径 rand 一个值,分别 ...

  8. 【UOJ207】共价大爷游长沙(Link-Cut Tree,随机化)

    [UOJ207]共价大爷游长沙(Link-Cut Tree,随机化) 题面 UOJ 题解 这题太神了 \(\%\%\%myy\) 看到动态的维护边很容易的想到了\(LCT\) 然后能否堵住一条路 我们 ...

  9. 「UOJ207」共价大爷游长沙

    「UOJ207」共价大爷游长沙 解题思路 : 快速判断两个集合是否完全相等可以随机点权 \(\text{xor}\) 的思路可以用到这道题上面,给每一条路径随机一个点权,维护出经过每一条边的点权的 \ ...

随机推荐

  1. windows安装程序制作

    作为一个学计算机的,现在才知道那些安装软件都是用软件封装工具封装起来的. 我们写好exe以后可以下载一个Inno setup5 对其打包成可安装的软件,期间可加入图标,readme,等等一些东西.

  2. RocketMQ 消费者

    本文分析 DefaultMQPushConsumer,异步发送消息,多线程消费的情形. DefaultMQPushConsumerImpl MQClientInstance 一个客户端进程只有一个 M ...

  3. 六:flask-自定义URL转换器

    flask进行url参数匹配的时候,是继承的werkzeug.routing.BaseConverter库进行重写的 导入看源码 里面有所有的URL参数数据类型的判断 也就是说,可以继承过后实现自己的 ...

  4. python学习笔记:(八)条件语句

    if语句,python中if语句的一般形式如下: conditon1为真,执行statement_block_1 condition1为假,判断conition_2,如果condition_2为真,执 ...

  5. Elasticsearch 安装head插件

    一.简介 elasticsearch-head是一个界面化的集群操作和管理工具,可以对集群进行傻瓜式操作.你可以通过插件把它集成到es(首选方式),也可以安装成一个独立webapp. Elastics ...

  6. spring几种获取 HttpServletRequest 对象的方式

    以下的 request 实例都编号了,一共 4 种 方式 1.@Autowired 方式2.public void Test(HttpServletRequest request1, HttpServ ...

  7. Pytorch搭建卷积神经网络用于MNIST分类

    import torch from torch.utils.data import DataLoader from torchvision import datasets from torchvisi ...

  8. Linux 后台执行python或者java代码的命令

    1.nohup 命令操作后台执行程序 后台启动 nohup python app.py params1 > nohup.out >& & 查看后台进程启动 jobs -l ...

  9. argparse命令行传参

    import argparse parser = argparse.ArgumentParser(description='manual to this script') # 创建解析器,及其描述 p ...

  10. 配置DHCP中继

    本实验模拟企业网络场景.某公司分部的网络由交换机S1和网关路由器R1组成,员工终端PC-1和PC-2都连接在S1上.公司要求分部内所有员工主机的IP地址都通过总部的DHCP服务器自动获取.分部网关路由 ...