「UOJ207」共价大爷游长沙
「UOJ207」共价大爷游长沙
解题思路 :
快速判断两个集合是否完全相等可以随机点权 \(\text{xor}\) 的思路可以用到这道题上面,给每一条路径随机一个点权,维护出经过每一条边的点权的 \(\text{xor}\) 值判断是否和全集相等即可。
因为要支持删边加边操作,可以用一棵 \(\text{lct}\) 来维护。对于删边,相当于是原来经过这条边的路径要改为从新的树上的那条路径经过,那只要将原有的 \(\text{xor}\) 值修改过去即可。
/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf ((int)(1e9))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 1000005;
map<int, int> mp[N];
int n, m, cnt, id;
struct Node{ int a, b, c; } dd[N];
namespace LCT{
int ch[N][2], val[N], rev[N], tag[N], fa[N], s[N];
#define P(u) (ch[fa[u]][1] == u)
#define IS(u) (ch[fa[u]][0] != u && ch[fa[u]][1] != u)
inline void update(int u){
s[u] = val[u] ^ s[ch[u][0]] ^ s[ch[u][1]];
}
inline void pushdown(int u){
if(rev[u]){
rev[u] = 0, swap(ch[u][0], ch[u][1]);
if(ch[u][0]) rev[ch[u][0]] ^= 1;
if(ch[u][1]) rev[ch[u][1]] ^= 1;
}
if(tag[u]){
val[u] ^= tag[u];
if(ch[u][0]) tag[ch[u][0]] ^= tag[u];
if(ch[u][1]) tag[ch[u][1]] ^= tag[u];
tag[u] = 0;
}
}
inline void rotate(int u){
int F = fa[u], w = P(u), G = fa[F];
if(!IS(F)) ch[G][P(F)] = u; fa[u] = G;
ch[F][w] = ch[u][w^1], fa[ch[u][w^1]] = F;
ch[u][w^1] = F, fa[F] = u, update(F);
}
inline void splay(int u){
static int st[N], top; st[top=1] = u;
for(int i = u; !IS(i); i = fa[i]) st[++top] = fa[i];
for(int i = top; i; i--) pushdown(st[i]);
for(int F = fa[u]; !IS(u); rotate(u), F = fa[u])
if(!IS(F)) rotate(P(u) == P(F) ? F : u);
update(u);
}
inline void access(int u){
for(int c = 0; u; c = u, u = fa[u])
splay(u), ch[u][1] = c, update(u);
}
inline void makeroot(int u){
access(u), splay(u), rev[u] ^= 1;
}
inline void link(int x, int y){
makeroot(x), fa[x] = y;
}
inline void cut(int x, int y){
makeroot(x), access(y), splay(y);
ch[y][0] = fa[x] = 0;
}
inline int query(int x){
makeroot(x), access(x), splay(x);
return s[x];
}
inline void change(int x, int y, int z){
makeroot(x), access(y), splay(y);
tag[y] ^= z, pushdown(y);
}
}
int main(){
read(id), read(n), read(m), id = n;
for(int i = 1, x, y; i < n; i++){
read(x), read(y), ++id;
LCT::link(x, id), LCT::link(y, id);
mp[x][y] = mp[y][x] = id;
}
int XOR = 0;
for(int i = 1, op, a, b, c, d; i <= m; i++){
read(op);
if(op == 1){
read(a), read(b), read(c), read(d);
int e = mp[a][b], tmp = LCT::query(e);
LCT::cut(a, e), LCT::cut(b, e), e = ++id;
mp[a][b] = mp[b][a] = 0;
mp[c][d] = mp[d][c] = e;
LCT::link(c, e), LCT::link(d, e);
LCT::change(a, b, tmp);
}
if(op == 2){
read(a), read(b);
int tmp = 1ll * rand() * rand() % ((int)1e9);
LCT::change(a, b, tmp), XOR ^= tmp;
dd[++cnt] = (Node){ a, b, tmp };
}
if(op == 3){
read(d);
a = dd[d].a, b = dd[d].b, c = dd[d].c;
LCT::change(a, b, c), XOR ^= c;
}
if(op == 4){
read(a), read(b);
puts(LCT::query(mp[a][b]) == XOR ? "YES" : "NO");
}
}
return 0;
}
「UOJ207」共价大爷游长沙的更多相关文章
- 【UOJ207】共价大爷游长沙(Link-Cut Tree,随机化)
[UOJ207]共价大爷游长沙(Link-Cut Tree,随机化) 题面 UOJ 题解 这题太神了 \(\%\%\%myy\) 看到动态的维护边很容易的想到了\(LCT\) 然后能否堵住一条路 我们 ...
- UOJ207:共价大爷游长沙
题面 UOJ Sol 神题 给每个点对随机一个权值,把这两个点的权值异或上这个随机的值 用\(LCT\)维护子树信息,若子树异或和为所有点对的异或和那么就是答案 大常数代码 # include < ...
- 【uoj207】 共价大爷游长沙
http://uoj.ac/problem/207 (题目链接) 题意 给出一棵无根树,4种操作:在路径集合中加入一条路径,在路径集合中删除一条路径,删一条边加一条边,查询一条边是否被集合中所有路径经 ...
- UOJ #207. 共价大爷游长沙 [lct 异或]
#207. 共价大爷游长沙 题意:一棵树,支持加边删边,加入点对,删除点对,询问所有点对是否经过一条边 一开始一直想在边权上做文章,或者从连通分量角度考虑,比较接近正解了,但是没想到给点对分配权值所以 ...
- 【刷题】UOJ #207 共价大爷游长沙
火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编号为 \(1\) 到 ...
- UOJ #207. 共价大爷游长沙
#207. 共价大爷游长沙 链接:http://uoj.ac/problem/207 题意:给一棵树,要求支持加边.删边.询问一条边是否被所有路径覆盖.同时路径端点集合有加入与删除操作. 想法: 考虑 ...
- 【UOJ#207】共价大爷游长沙
题目链接 题目描述 火车司机出秦川,跳蚤国王下江南,共价大爷游长沙.每个周末,勤劳的共价大爷都会开车游历长沙市. 长沙市的交通线路可以抽象成为一个 \(n\) 个点 \(n−1\) 条边的无向图,点编 ...
- 【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息
题目描述 给出一棵树和一个点对集合S,多次改变这棵树的形态.在集合中加入或删除点对,或询问集合内的每组点对之间的路径是否都经过某条给定边. 输入 输入的第一行包含一个整数 id,表示测试数据编号,如第 ...
- [UOJ207]共价大爷游长沙
UOJ sol 这题真是太神啦! 对于S集合中的每个点对,给他们随机附上一个相同权值. 两个点在边(x,y)的两侧当且仅当一个点在x的子树中,另一个点不在x的子树中(假设x是y的儿子) 维护一下子树点 ...
随机推荐
- 在ASP.NET中备份和还原数据库
昨天看了<C#项目实录>中的进销存管理系统,和其他书里讲的案例一样,无非也就是数据库增删查改,但是这个进销存系统中有一个备份和还原数据库的功能,蛮有兴趣的,看了一下代码,原来如此, ...
- 伪ajax操作
什么是伪Ajax操作? 说白了就是假的ajax操作,但是它和正常的ajax操作的目的是一样的,把前端的信息发送到后台 先看一下代码吧! ajax.html <form action=" ...
- flask插件系列之flask_cors跨域请求
前后端分离在开发调试阶段本地的flask测试服务器需要允许跨域访问,简单解决办法有二: 使用flask_cors包 安装 pip install flask_cors 初始化的时候加载配置,这样就可以 ...
- 概述sysfs文件系统【转】
转自:http://blog.csdn.net/npy_lp/article/details/78933292 内核源码:linux-2.6.38.8.tar.bz2 目标平台:ARM体系结构 sys ...
- static作用(修饰函数、局部变量、全局变量)转自http://www.cnblogs.com/stoneJin/archive/2011/09/21/2183313.html
static作用(修饰函数.局部变量.全局变量) 在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条. (1)先来介绍它的第一条也是最重要的一条:隐藏. 当我们同时编译多个文件 ...
- Ubuntu命令设置ip网关dns
本文系转载,介绍Ubuntu如何设置IP和网络来连接网络 如果是在虚拟机中使用Ubuntu,那么设置之前请先参照我的上一遍文章虚拟机Net方式设置连接外网中的网络设置部分,先设置好主机的网络,然后配置 ...
- Machine Learning系列--隐马尔可夫模型的三大问题及求解方法
本文主要介绍隐马尔可夫模型以及该模型中的三大问题的解决方法. 隐马尔可夫模型的是处理序列问题的统计学模型,描述的过程为:由隐马尔科夫链随机生成不可观测的状态随机序列,然后各个状态分别生成一个观测,从而 ...
- jmeter主要组件
1.测试计划(Test plan) 2.线程组(Thread Group) 3.配置原件(Configuration) 4.逻辑控制器(Login Controller) 5.取样器(Sampler) ...
- Dev Express 安装
Dev Express 安装 点击DevExpressUniversalTrialComplete-20151209.exe开始安装 选择需要安装的产品 选择需要安装的产品目录,这里设置为D盘 开 ...
- ssh使两台机器建立连接
ssh利用口令建立连接过程: 客户端--> 发送连接请求 --> 远程主机 --> 返回远程主机的公钥 --> 公钥加密客户端私钥+客户端公钥返回远程主机 --> 远程主 ...