luogu P4299 首都
题目描述
在X星球上有N个国家,每个国家占据着X星球的一座城市。由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的。
X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失,而B国的国土也将归A国管辖。A国国王为了加强统治,会在A国和B国之间修建一条公路,即选择原A国的某个城市和B国某个城市,修建一条连接这两座城市的公路。
同样为了便于统治自己的国家,国家的首都会选在某个使得其他城市到它距离之和最小的城市,这里的距离是指需要经过公路的条数,如果有多个这样的城市,编号最小的将成为首都。
现在告诉你发生在X星球的战事,需要你处理一些关于国家首都的信息,具体地,有如下3种信息需要处理:
A x y:表示某两个国家发生战乱,战胜国选择了x城市和y城市,在它们之间修建公路(保证其中城市一个在战胜国另一个在战败国)。Q x:询问当前编号为x的城市所在国家的首都。Xor:询问当前所有国家首都编号的异或和。
题解
有link操作还询问重心,是让我们在维护LCT的时候维护一下重心。
这道题用到了LCT的很多性质。
比如说我们link了两棵树,那么我们拿出两棵树的重心,那么重心一定在这两条链的路径上,我们把这条链split出来。
根据splay的性质,这条链构成的splay的高度是期望log的。
然后我们就可以从根开始搜索了。
既然是log的,那么我们就可以用类似树上二分的方法找了。
连通性这种东西用并查集维护就可以了。
LCT维护子树信息时link一定要splay(y)!!!!!
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100009
using namespace std;
char sh[];
int f[N],ch[N][],s[N],si[N],fa[N],n,m,st[N],xoR;
bool rev[N];
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline int find(int x){return f[x]=f[x]==x?x:find(f[x]);}
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline bool ge(int x){return ch[fa[x]][]==x;}
inline void pushup(int x){s[x]=s[ch[x][]]+s[ch[x][]]+si[x]+;}
inline void pushdown(int x){
if(rev[x]){
rev[ch[x][]]^=;rev[ch[x][]]^=;rev[x]^=;
swap(ch[x][],ch[x][]);
}
}
inline void rotate(int x){
int y=fa[x],o=ge(x);
if(isroot(x))return;
ch[y][o]=ch[x][o^];fa[ch[y][o]]=y;
if(!isroot(y))ch[fa[y]][ge(y)]=x;fa[x]=fa[y];
fa[y]=x;ch[x][o^]=y;
pushup(y);pushup(x);
}
inline void push(int x){
if(!isroot(x))push(fa[x]);
pushdown(x);
}
inline void splay(int x){
push(x);
while(!isroot(x)){
int y=fa[x];
if(isroot(y))rotate(x);
else rotate(ge(x)==ge(y)?y:x),rotate(x);
}
pushup(x);
}
inline void access(int x){
for(int y=;x;y=x,x=fa[x]){
splay(x);
si[x]-=s[y];si[x]+=s[ch[x][]];ch[x][]=y;
pushup(x);
}
}
inline void makeroot(int x){access(x);splay(x);rev[x]^=;}
inline void split(int x,int y){makeroot(x);access(y);splay(y);}
inline void link(int x,int y){split(x,y);fa[x]=y;si[y]+=s[x];pushup(y);}
inline int search(int x){
int suml=,sumr=,rs,ls,sum=s[x]>>,o=s[x]&,now=2e9,xx,yy;
while(x){
pushdown(x);
xx=suml+s[ls=ch[x][]];yy=sumr+s[rs=ch[x][]];
if(xx<=sum&&yy<=sum){
if(o){now=x;break;}
else if(x<now)now=x;
}
if(xx<yy)suml+=s[ls]+si[x]+,x=rs;
else sumr+=s[rs]+si[x]+,x=ls;
}
return now;
}
int main(){
n=rd();m=rd();int x,y;
for(int i=;i<=n;++i)s[i]=,f[i]=i,xoR^=i;
for(int i=;i<=m;++i){
scanf("%s",sh);
if(sh[]=='A'){
x=rd();y=rd();//if(find(x)==find(y))continue;
link(x,y);x=find(x);y=find(y);
split(x,y);int z=search(y);
xoR=xoR^x^y^z;
f[x]=f[y]=f[z]=z;
}
else if(sh[]=='Q'){x=rd();printf("%d\n",find(x));}
else printf("%d\n",xoR);
}
return ;
}
luogu P4299 首都的更多相关文章
- Luogu P4299 首都 LCT
既然是中文题目,这里便不给题意. 分析: 这个题的做法据说是启发式合并? 但是我不会啊…… 进入正题,LCT是怎样做掉这道题的.记得在前面的一篇<大融合>的题解中,介绍过LCT维护子树信息 ...
- P4299 首都
题目 P4299 首都 做法 这题是动态维护树的重心,连边后找到两棵树的重心拉一条链(性质:新重心在链上),然后暴力爬 要注意: 1.是找重心的过程中要先把旋转标记放下来,因为\(Splay(x)\) ...
- 洛谷P4299 首都(BZOJ3510)(LCT,树的重心,二分查找)
Update:原来的洛谷U21715已成坑qwq 已经被某位管理员巨佬放进公共题库啦!又可以多一个AC记录啦! 洛谷题目传送门 其实也可以到这里交啦 思路分析 动态维护树的重心 题目中说到国家的首都会 ...
- [洛谷P4299] 首都
题目传送门 还是维护子树信息. 但是这里多了一个找重心的操作. 这里有一个关于树重心的结论,据说可以用反证法证明.反正我不会证 就是:新的重心一定在原来两个重心之间的那条树链上. 这样我们逐步缩小搜索 ...
- [总结] LCT学习笔记
\(emmm\)学\(lct\)有几天了,大概整理一下这东西的题单吧 (部分参考flashhu的博客) 基础操作 [洛谷P1501Tree II] 题意 给定一棵树,要求支持 链加,删边加边,链乘,询 ...
- [luogu P2521] [HAOI2011]防线修建
[luogu P2521] [HAOI2011]防线修建 题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国 ...
- Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)
Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
- luogu p1268 树的重量——构造,真正考验编程能力
题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...
随机推荐
- SpringMvc的Controller singleton synchronized
SpringMvc的controller是singleton的(非线程安全的) - lvyuanj的专栏 - CSDN博客 https://blog.csdn.net/lvyuanj/article/ ...
- Vmware由于centos升级内核不可运行(C header files matching your running kernel were not found)的解决方案
C header files matching your running kernel were not found. Refer to your distribution's documentati ...
- 网站之robots.txt文件
一.robots.txt是什么? robots.txt是一个纯文本文件,在这个文件中网站管理者可以声明该网站中不想被搜索引擎访问的部分,或者指定搜索引擎只收录指定的内容. 当一个搜索引擎(又称搜索 ...
- artTemplate之初印象
介绍 art-template 是JavaScript模板引擎,是一个简约.超快的模板引擎. 它采用作用域预声明的技术来优化模板渲染速度,从而获得接近 JavaScript 极限的运行性能,并且同时支 ...
- day 7 -1 进程理论知识
一.进程的定义 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在早期面向进程设计的计算机结构中,进程是程序的基本执行实 ...
- 谈谈git/github
先说git/github操作 ->关于git/github操作的好文章已经非常多,如: github使用指南 廖雪峰的git教程 本文的目的在于,积累自己平时相关的操作和想法,记录下来,形成自己 ...
- Python 基础知识----流程控制
判断语句 循环语句 嵌套
- 移动端Web界面滚动touch事件
解决办法一: elem.addEventListener( 'touchstart', fn, { passive: false } ); 解决办法二: * { touch-action: pan-y ...
- DAY04、流程控制if、while、for
一.if 判断 语法一: if 条件: # 以下是上一条if 的子代码块 print(子代码1) print(子代码2) print(子代码3) 示例: # 路边飘过一个生物,要不要表白? sex = ...
- 老男孩python学习自修第十四天【序列化和json】
序列化是使用二进制的方式加密列表,字典或集合,反序列化是解密的过程:序列化开启了两个独立进程进行数据交互的通路 使用pickle进行序列化和反序列化 例如: pickle_test.py #!/usr ...