【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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466923.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ping 命令的几种使用方法?

ping命令的几种使用方法&#xff1f;它是最基本&#xff0c;最常用的&#xff0c;测试物理网络的命令&#xff0c;它的使用频率很高&#xff0c;主要用于确定本地主机和另一台主机能否成功进行发送或接收数据包&#xff0c;根据返回的信息&#xff0c;我们就可以判断TCP/IP参数…

MongoDB基本应用操作整理

启动服务&#xff1a;mongod --dbpathg:/mongo/data 访问服务器&#xff0c;如下&#xff1a; mongodb这个软件的端口是27017 可以把mongo服务配置成系统服务。 使用命令如下&#xff1a; mongod --dbpathg:/mongo/data --logpathg:/mongo/mongo.log --install 在Mongo中就三…

周五跟大佬喝酒,顺便打了个球

这是前天发生的事情&#xff0c;昨天写好了文章&#xff0c;今天才发出来&#xff0c;但是名字还是想写成昨晚小聚。昨晚逍遥和啊尚过来找我打球&#xff0c;很开心&#xff0c;虽然酝酿了好久关于这次的活动&#xff0c;但是它真的发生时&#xff0c;我还是显得有些突兀和紧张…

安装Cygwin

Cygwin安装 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 下载cygwin&#xff1a;https://www.cygwin.com/ 箭头指的地方点一下就是安装该软件&#xff0c;开始要安装的一些软件&#xff0c;gcc&#xff0c;gdb&#xff0c;make&#xff0c;ssh等等。…

修练8年C++面向对象程序设计之体会

面向对象程序设计语言很多&#xff0c;如Smalltalk、Ada、Eiffel、Object Pascal、Visual Basic、C等等。C语言最讨人喜欢&#xff0c;因为它兼容C 语言&#xff0c;并且具备C 语言的性能。近几年&#xff0c;一种叫Java 的纯面向对象语言红极一时&#xff0c;不少人叫喊着要用…

JavaScript——使用对话框

alert 该对话框只用于提醒&#xff0c;不能对脚本产生任何改变。它只有一个参数&#xff0c;即为需要提示的信息&#xff0c;没有返回confirm 该对话框一般用于确认信息&#xff0c;它只有一个参数&#xff0c;返回值为true或falseprompt 该对话框可以进行输入&#xff0c;并返…

飞机上一般是什么操作系统?

之前波音737MAX空难失事事件牵动人心&#xff0c;让人对航空出行又平添了一份不信任&#xff0c;根据最新消息显示&#xff0c;美国联邦航空局对737 MAX机型的大量评估授权给波音公司自身进行&#xff0c;安全评估存在严重缺陷。也传出了波音737 MAX客机的培训都是通过平板电脑…

地铁上怎么那么多钢管女郎?

每天早上拖着疲惫的身体&#xff0c;逆着人流走向地铁站&#xff0c;人好多。开门&#xff0c;上车&#xff0c;想找根钢管来平衡一下身体&#xff0c;没想到有美女在抱着钢管跳舞。。。换个钢管吧&#xff0c;又有一个抱着钢管的美女。。。请问一下各位女士&#xff0c;你们那…

排查一个触摸屏驱动问题

今天跟同事看一个TP驱动&#xff0c;上电后日志都正常&#xff0c;但是触摸没反应&#xff0c;然后开始排查。上电后可以正常读到芯片的chip ID&#xff0c;那说明I2C是通讯正常的&#xff0c;也可以说明触摸芯片的供电也是正常的。基于这个&#xff0c;我搬来示波器&#xff0…

javaScript——内置函数1

JavaScript中有两种函数&#xff1a;一种是语言内部事先定义好的函数叫内置函数&#xff0c;另一种是自己定义的 函数。使用内置函数&#xff0c;可提高编程效率&#xff0c;其中有六种内置函数。 eval函数 eval&#xff08;expr&#xff09;函数可以把一个字符串当作一个JavaS…

vmware安装ubuntu

vmware安装Ubuntu 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 &#xff08;1&#xff09; 单击”Power on this virtual machine”开始安装Ubuntu系统 经过一段时间的等待出现如下界面,单击”Install Ubuntu”进行安装 在安装的时候&#xff0…

SQL server挂了之后

今天在服务器上的SQL server挂了之后,重新装了,可老提示什么狗P程序被挂起的信息,最后不得不细找原因,功夫不负有心人,终于找出了病症所在,K,我要早知道这么简单,就再也不装系统了.....汗死,详情如下,做个备份,以便今后再碰到类似问题有地方查! 先运行你的安装程序&#xff0c;…

AWS 免费套餐

https://amazonaws-china.com/cn/free/ 需要的可以看下&#xff0c;我准备搞一个RDS。 转载于:https://www.cnblogs.com/hupo376787/p/8268562.html

C++指针的应用

C指针 文章中我们介绍了指针的基本概念和应用简介。我们有提到指针可以使用在链表、队列和二叉树&#xff0c;等等。但是这些都会比较复查&#xff0c;后面"数据结构” 时&#xff0c;我们会用专门的章节来讲解这些知识。这篇文章&#xff0c;详细的探讨一下指针和其他关联…

Matplotlib——创建散点图

入门&#xff1a; 导入所用到的包 import numpy as np import matplotlib.pyplot as plt as 是对包起一个名字&#xff0c;便于后边程序的编写无颜色差别 figplt.figure() #建立一个画布 axfig.add_subplot(111) #在画布中建立图表&#xff0c;fig.add_subplot(…

vmwaretools安装

vmwaretools安装 宗旨&#xff1a;技术的学习是有限的&#xff0c;分享的精神是无限的。 vmware的作用&#xff1a;windows和linux之间文件拖文件很方便&#xff0c;但是我一般是使用samba服务器&#xff0c;后面介绍samba服务器。 &#xff08;1&#xff09;单击菜单栏上的”…

Android - Glide4.4.0使用

错误信息 java.lang.NoSuchMethodError: No static method getFont(Landroid/content/Context;ILandroid/util/TypedValue;ILandroid/widget/TextView;)Landroid/graphics/Typeface; in class Landroid/support/v4/content/res/ResourcesCompat; or its super classes (declara…

渐入“衰”境:警惕企业的六大老人病

1.组织惯性成员的思维、行为惯性容易汇聚成为阻碍组织前行的组织惯性。在企业管理的实施过程中&#xff0c;组织成员特别是老人有时并不按照新的架构流程和制度规范去工作。这不全是因为大家不接受新的系统&#xff0c;而是一工作就回到原先习惯的状态—我们把这个现象称为组织…

机器学习——支持向量机主要思想

概念&#xff1a;支持向量运算的分类器&#xff0c;在数据上应用基本形式的SVM分类器就可以得到低错误的结果&#xff0c;能够对训练集以外的数据点做出很好的分类决策。 名词&#xff1a; 支持向量&#xff1a;离分离超平面最近的那些点&#xff0c;需要找到最大化支持向量到分…

哇、、、、C++ 实现单向链表

之前相关的文章 C语言&#xff0c;链表 Linux内核链表 #什么是链表 链表是一种基本的数据结构&#xff0c;之前我在C语言里面写过链表的知识&#xff0c;现在延申到C&#xff0c;不管是什么语言&#xff0c;链表表示的是一种数据结构&#xff0c;跟语言没有强相关性的。 如果我…