【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息
题目描述
给出一棵树和一个点对集合S,多次改变这棵树的形态、在集合中加入或删除点对,或询问集合内的每组点对之间的路径是否都经过某条给定边。
输入
输入的第一行包含一个整数 id,表示测试数据编号,如第一组数据的id=1,样例数据的 id 可以忽略。
输入的第二行包含两个整数 n,m,分别表示图中的点数,以及接下来会发生的事件数,事件的定义下文中会有描述。初始时 S 为空。
接下来 n−1 行,每行两个正整数 x,y,表示点 x 和点 y 之间有一条无向边。
接下来 m 行,每行描述一个事件,每行的第一个数 type 表示事件的类型。
若type=1,那么接下来有四个正整数x,y,u,v,表示先删除连接点x和点y的无向边,保证存在这样的无向边,然后加入一条连接点u和点v的无向边,保证操作后的图仍然满足题中所述条件。
若type=2,那么接下来有两个正整数 x,y,表示在 S 中加入点对 (x,y)。
若type=3,那么接下来有一个正整数 x,表示删除第 x 个加入 S 中的点对,即在第 x 个 type=2 的事件中加入 S 中的点对,保证这个点对存在且仍然在 S 中。
若 type=4,那么接下来有两个正整数 x,y,表示小L询问守在连接点 x 和点 y 的边上是否一定能见到共价大爷,保证存在这样的无向边且此时 S 不为空。
输出
对于每个小L的询问,输出“YES”或者“NO”(均不含引号)表示小L一定能或者不一定能见到共价大爷。
样例输入
0
5 7
1 2
1 3
2 4
1 5
2 1 5
1 1 5 2 5
4 2 5
2 1 4
4 2 5
3 1
4 2 4
题解
随机化+LCT维护子树信息
对与每个点对,随机一个权值,把这个权值异或到这两个点上。那么对于查询,如果 x 为树根时,y 子树中的所有点的权值的异或和等于所有点对的异或和,则视为所有点对间的路径都经过 x-y 。(别问我怎么想出来的。。。做过一道类似的题)
当权值范围足够大时可以近似视为正确。
由于树的形态是变化的,因此需要使用LCT维护子树信息,具体方法参见这里。
注意维护子树信息的LCT:link时需要makeroot(x),makeroot(y);修改时需要makeroot(x)而不是简单的splay(x);查询时需要先makeroot(x)。
时间复杂度 $O(LCT·n\log n)$
#include <cstdio>
#include <algorithm>
#define N 100010
using namespace std;
int fa[N] , c[2][N] , rev[N] , w[N] , sum[N] , vx[N * 3] , vy[N * 3] , vw[N * 3] , tot;
inline void pushup(int x)
{sum[x] = sum[c[0][x]] ^ sum[c[1][x]] ^ w[x];
}
inline void pushdown(int x)
{if(rev[x]){int l = c[0][x] , r = c[1][x];swap(c[0][l] , c[1][l]) , rev[l] ^= 1;swap(c[0][r] , c[1][r]) , rev[r] ^= 1;rev[x] = 0;}
}
inline bool isroot(int x)
{return c[0][fa[x]] != x && c[1][fa[x]] != x;
}
void update(int x)
{if(!isroot(x)) update(fa[x]);pushdown(x);
}
inline void rotate(int x)
{int y = fa[x] , z = fa[y] , l = (c[1][y] == x) , r = l ^ 1;if(!isroot(y)) c[c[1][z] == y][z] = x;fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y;pushup(y) , pushup(x);
}
inline void splay(int x)
{int y , z;update(x);while(!isroot(x)){y = fa[x] , z = fa[y];if(!isroot(y)){if((c[0][y] == x) ^ (c[0][z] == y)) rotate(x);else rotate(y);}rotate(x);}
}
inline void access(int x)
{int t = 0;while(x) splay(x) , w[x] ^= sum[c[1][x]] ^ sum[t] , c[1][x] = t , t = x , x = fa[x];
}
inline void makeroot(int x)
{access(x) , splay(x) , swap(c[0][x] , c[1][x]) , rev[x] ^= 1;
}
inline void link(int x , int y)
{makeroot(x) , makeroot(y) , fa[x] = y , w[y] ^= sum[x] , pushup(y);
}
inline void cut(int x , int y)
{makeroot(x) , access(y) , splay(y) , fa[x] = c[0][y] = 0 , pushup(y);
}
int main()
{srand(20011011);int n , m , i , opt , x , y , u , v , now = 0;scanf("%*d%d%d" , &n , &m);for(i = 1 ; i < n ; i ++ ) scanf("%d%d" , &x , &y) , link(x , y);while(m -- ){scanf("%d%d" , &opt , &x);if(opt == 1) scanf("%d%d%d" , &y , &u , &v) , cut(x , y) , link(u , v);else if(opt == 2){scanf("%d" , &y);vx[++tot] = x , vy[tot] = y , vw[tot] = (rand() << 15) + rand() , now ^= vw[tot];makeroot(x) , w[x] ^= vw[tot] , pushup(x);makeroot(y) , w[y] ^= vw[tot] , pushup(y);}else if(opt == 3){now ^= vw[x];makeroot(vx[x]) , w[vx[x]] ^= vw[x] , pushup(vx[x]);makeroot(vy[x]) , w[vy[x]] ^= vw[x] , pushup(vy[x]);}else scanf("%d" , &y) , makeroot(x) , access(y) , splay(y) , puts(sum[x] == now ? "YES" : "NO");}return 0;
}
转载于:https://www.cnblogs.com/GXZlegend/p/8244009.html
【uoj#207】共价大爷游长沙 随机化+LCT维护子树信息相关推荐
- [UOJ#207]共价大爷游长沙
题目大意 一颗会动的树. 有一个点对集合会变. 每次询问一条树边,问集合内所有点对之间的路径是否都经过该边. 维护虚边信息的LCT 终于无聊来补了这题 每个点对随机一个10^9内的权值 然后给两端点的 ...
- 【UOJ207】共价大爷游长沙【LCT】【异或】【随机化】
传送门 题意:维护一棵无权树和一个路径集合SSS,支持以下操作: 断边连边 在SSS加入中加入一条路径 删除SSS中的一条路径 询问是否SSS中的所有路径都经过了边(x,y)(x,y)(x,y) n≤ ...
- bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530 LCT维护子树 siz .设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的si ...
- 【uoj207】 共价大爷游长沙
http://uoj.ac/problem/207 (题目链接) 题意 给出一棵无根树,4种操作:在路径集合中加入一条路径,在路径集合中删除一条路径,删一条边加一条边,查询一条边是否被集合中所有路径经 ...
- UOJ207 共价大爷游长沙
考虑到路径是有向的,不是很好维护. 如果路径无向的话,可以直接转化为链加和查询操作. 既然有向的话,不妨考虑一波hash. 对于一组询问x,y,可以把树划分为两颗子树. 合法显然需要满足 x子树的起点 ...
- LCT维护子树信息(BZOJ4530:[BJOI2014]大融合)
题面 没有权限号的可以去LOJ Sol 大家都知道,\(LCT\)上有许多实边和虚边 实边就是每棵\(Splay\)上的既认父亲又认儿子的边 虚边就是\(Splay\)和\(Splay\)之间只认父亲 ...
- BZOJ 4530 大融合 LCT维护子树信息
题意: N<=1e5个点,Q<=1e5个操作. 支持加一条边(u,v)(保证图是森林).询问经过边(u,v)的简单路径条数(保证(u,v)存在). 分析: 数据结构学傻了的我,表示并不会用 ...
- LOJ 121 「离线可过」动态图连通性——LCT维护删除时间最大生成树 / 线段树分治...
题目:https://loj.ac/problem/121 离线,LCT维护删除时间最大生成树即可.注意没有被删的边的删除时间是 m+1 . 回收删掉的边的节点的话,空间就可以只开 n*2 了. #i ...
- bzoj 4736: 温暖会指引我们前行 (LCT 维护最大生成树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4736 题面: 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出 ...
最新文章
- LEADTOOLS HTML5/JavaScript 实现客户端图像处理
- opencv 图像分割
- 湖南网络推广浅谈网站首页降权怎么办?
- 把 Redis 当作队列来用,真的合适吗?
- pb 如何判断缺纸_如何快速判断是否低估?四种相对估值法应用精析
- 看奥运之二:现场看男子体操团体决赛
- 测试龙芯 LoongArch .NET之 使用 FastTunnel 做内网穿透远程计算机
- 信息学奥赛一本通 2028:【例4.14】百钱买百鸡
- 信息学奥赛一本通(1323:【例6.5】活动选择)
- linux内核源码目录结构分析
- SSL-ZYC 2416 条形图
- php wap微信h5支付接口,微信支付开发H5支付
- 智慧路灯网关下的校园智慧路灯照明解决方案
- ST语言和C语言的区别 STC
- 盒子模型补充知识汇总
- appstore ip地址
- 自己动手写一个小型的TCP/IP协议
- ncnn 载入insightface训练好的性别年龄识别模型
- Python Tkinter 下载器 多任务下载+多线程下载+多任务断点续存
- ASCII Binary