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风格的题 ...
随机推荐
- Linux 典型应用之Mysql
Mysql 的安装及连接 删除默认安装的 mariadb数据库 yum remove mariadb-libs.x86_64 mysql源下载的网址 https://dev.mysql.com/dow ...
- day 7-20 视图,触发器,事务
一.视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的 ...
- leetcode资料整理
注:借鉴了 http://m.blog.csdn.net/blog/lsg32/18712353 在Github上提供leetcode有: 1.https://github.com/soulmachi ...
- Ubuntu18.04安装mysql5.7
Ubuntu18.04安装mysql5.7 1.1安装 首先执行下面三条命令: # 安装mysql服务 sudo apt-get install mysql-server # 安装客户端 sudo a ...
- linux 下crontab -e 命令插入及保存
由于功能需要,用到linux定时任务. 一般我们都是crontab -e 进去写好定时任务,直接保存退出就可以了,如果是第一次创建定时任务, 系统会选择默认编辑器,就不好保存文件. 在网上参考了一篇文 ...
- linux audit审计(7)--读懂audit日志
让我们先来构造一条audit日志.在home目录下新建一个目录,然后配置一条audit规则,对这个目录的wrax,都记录审计日志: auditctl -w /home/audit_test -p wr ...
- echo "" > 和 echo "" >> 的区别
在写shell脚本中,如果判断一个文件已经存在,但希望重写这个文件,一般用如下方式 echo "" > file.txt 这个表示清空文件的内容,如果使用 echo “” & ...
- Chrome & QR Code Reader
Chrome & QR Code Reader Allows to generate a QR Code for the current page and scan a QR Code usi ...
- Java对象clone()的测试
Object中自带native clone()方法. 研究了一下用法. public class DeepCopyTest { public static void main(String[] arg ...
- SQL Server 只安装客户端的方法
只安装管理工具