BZOJ3510 首都
题目描述
在X星球上有N个国家,每个国家占据着X星球的一座城市。由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的。
X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失,而B国的国土也将归A国管辖。A国国王为了加强统治,会在A国和B国之间修建一条公路,即选择原A国的某个城市和B国某个城市,修建一条连接这两座城市的公路。
同样为了便于统治自己的国家,国家的首都会选在某个使得其他城市到它距离之和最小的城市,这里的距离是指需要经过公路的条数,如果有多个这样的城市,编号最小的将成为首都。
现在告诉你发生在X星球的战事,需要你处理一些关于国家首都的信息,具体地,有如下3种信息需要处理:
1、A x y:表示某两个国家发生战乱,战胜国选择了x城市和y城市,在它们之间修建公路(保证其中城市一个在战胜国另一个在战败国)。
2、Q x:询问当前编号为x的城市所在国家的首都。
3、Xor:询问当前所有国家首都编号的异或和。
输入
第一行是整数N,M,表示城市数和需要处理的信息数。
接下来每行是一个信息,格式如题目描述(A、Q、Xor中的某一种)。
输出
输出包含若干行,为处理Q和Xor信息的结果。
样例输入
10 10
Xor
Q 1
A 10 1
A 1 4
Q 4
Q 10
A 7 6
Xor
Q 7
Xor
样例输出
11
1
1
1
2
6
2
题解
LCT维护子树信息
看了好几个小时的题解还是半懂不懂orz
先考虑连接两棵树
有两个性质
1.重心必在点数多的子树内
2.点数多的子树上重心移动的距离不超过点数少的子树的点数
然后就是连上之后,把这条路径拉出来,dfs一遍,枚举选哪一个点,然后判一下最优就好了
// luogu-judger-enable-o2
//minamoto
#include<iostream>
#include<cstdio>
#include<algorithm>
using std::swap;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char obuf[<<],*o=obuf;
inline void print(int x){
if(x>) print(x/);
*o++=x%+;
}
const int N=;
int fa[N],st[N],sum[N],si[N],rev[N],ch[N][],top,s;
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline void pushup(int x){sum[x]=sum[ch[x][]]+sum[ch[x][]]+si[x]+;}
inline void pushdown(int x){
if(rev[x]){
swap(ch[x][],ch[x][]);
rev[ch[x][]]^=,rev[ch[x][]]^=;
rev[x]=;
}
}
void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][]==x;
if(!isroot(y)) ch[z][ch[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][d^]]=y,ch[y][d]=ch[x][d^],ch[x][d^]=y,pushup(y);
}
void down(int x){
if(!isroot(x)) down(fa[x]);
pushdown(x);
}
void splay(int x){
down(x);
for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
if(!isroot(y))
((ch[y][]==x)^(ch[z][]==y))?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
void access(int x){
for(int y=;x;x=fa[y=x])
splay(x),si[x]+=sum[ch[x][]],si[x]-=sum[ch[x][]=y],pushup(x);
}
void makeroot(int x){
access(x),splay(x),rev[x]^=;
}
int findroot(int x){
access(x),splay(x),pushdown(x);
while(ch[x][]) pushdown(x=ch[x][]);
return x;
}
void split(int x,int y){
makeroot(x),access(y),splay(y);
}
void link(int x,int y){
split(x,y),fa[x]=y,si[y]+=sum[x],pushup(y);
}
void dfs(int x){
pushdown(x);
if(ch[x][]) dfs(ch[x][]);
if(top>s) return;
st[++top]=x;
if(top>s) return;
if(ch[x][]) dfs(ch[x][]);
}
int main(){
//freopen("testdata.in","r",stdin);
int n=read(),m=read(),res=;
for(int i=;i<=n;++i) sum[i]=,res^=i;
while(m--){
char c;
while((c=getc())!='Q'&&c!='A'&&c!='X');
switch(c){
case 'A':{
int x=read(),y=read();
int tx=findroot(x),ty=findroot(y),ts;
res^=tx^ty;
splay(tx),splay(ty);
if(sum[tx]>sum[ty]||(sum[tx]==sum[ty]&&x<y)) swap(x,y),swap(tx,ty);
s=sum[tx],ts=sum[tx]+sum[ty],link(x,y),access(x),splay(ty);
top=,dfs(ty);int r=ty;
for(int i=;i<=top;++i){
splay(st[i]);int t=si[st[i]]++sum[ch[st[i]][]];
if(ts-t<t||(ts-t==t&&st[i]<=r)) r=st[i];
else break;
/*枚举原重心到连接点之间的路径
t表示枚举到某一点时另一棵子树的大小
如果这棵子树大于另一边或那啥,更新答案
否则之前的答案最优,直接退出*/
}
makeroot(r),res^=r;
break;
}
case 'Q':{
int x=read();
print(findroot(x)),*o++='\n';
break;
}
case 'X':{
print(res),*o++='\n';
break;
}
}
}
fwrite(obuf,o-obuf,,stdout);
return ;
}
BZOJ3510 首都的更多相关文章
- BZOJ3510 首都(LCT)
即动态维护树的重心.考虑合并后的新重心一定在两棵树的重心的连线上.于是对每个点维护其子树大小,合并时在这条链的splay上二分即可.至于如何维护子树大小,见https://blog.csdn.net/ ...
- BZOJ3510首都(LCT)
Description 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从 ...
- bzoj3510 首都 LCT 维护子树信息+树的重心
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3510 题解 首先每一个连通块的首都根据定义,显然就是直径. 然后考虑直径的几个性质: 定义:删 ...
- Bzoj3510首都
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- Some Conclusions.
目录 DP 四边形不等式 数论 & 数学 数据结构 树链剖分 左偏树的性质及\(O(n)\)的构造 图论 树 二分图 竞赛图 平面图 双连通分量 字符串 后缀自动机 复杂度分析 没什么好写的. ...
- LCT维护子树信息
有些题目,在要求支持link-cut之外,还会在线询问某个子树的信息.LCT可以通过维护虚边信息完成这个操作. 对于LCT上每个节点,维护两个两sz和si,后者维护该点所有虚儿子的信息,前者维护该点的 ...
- 【BZOJ3510】首都 LCT维护子树信息+启发式合并
[BZOJ3510]首都 Description 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打 ...
- 洛谷P4299 首都(BZOJ3510)(LCT,树的重心,二分查找)
Update:原来的洛谷U21715已成坑qwq 已经被某位管理员巨佬放进公共题库啦!又可以多一个AC记录啦! 洛谷题目传送门 其实也可以到这里交啦 思路分析 动态维护树的重心 题目中说到国家的首都会 ...
- 【bzoj3510】首都 LCT维护子树信息(+启发式合并)
题目描述 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失, ...
随机推荐
- 安装atop笔记
atop 官网: https://www.atoptool.nl/downloadatop.php 1.直接下载源码安装: https://www.atoptool.nl/download/atop- ...
- book pile SGU - 271
有n本书从上到下摞在一起,有两种操作.ADD(C)表示把一本新书C放到这一摞书的最顶上,ROTATE表示将前K本书进行反转.在一系列操作后输出最后书的顺序 分析: 当时听别人讲这个题的时候很懵逼,后来 ...
- nginx源码完全注释(1)ngx_alloc.h / ngx_alloc.c
首先看 ngx_alloc.h 文件,主要声明或宏定义了 ngx_alloc,ngx_calloc,ngx_memalign,ngx_free. /* * Copyright (C) Igor Sys ...
- ios加载本地html
UIWebView加载工程本地网页与本地图片 - (void)viewDidLoad { [super viewDidLoad]; NSString *filePath = [[NSBundle ma ...
- LVS集群中实现的三种IP负载均衡技术
LVS有三种IP负载均衡技术:VS/NAT,VS/DR,VS/TUN. VS/NAT的体系结构如图所示.在一组服务器前有一个调度器,它们是通过Switch/HUB相连接的.这些服务器 提供相同的网络服 ...
- 快速搭建Wordpress
1. 下载:ZentaoPMS作为Mysql Apach Php的基础环境: 2. 下载:Wordpress安装包: 3. 将Wordpress解压,放置于ZentaoPMS的Xampp的htdocs ...
- tornado异步请求非阻塞-乾颐堂
前言 也许有同学很迷惑:tornado不是标榜异步非阻塞解决10K问题的嘛?但是我却发现不是torando不好,而是你用错了.比如最近发现一个事情:某网站打开页面很慢,服务器cpu/内存都正常.网络状 ...
- UDP问题
这两天使用C#的UdpClient,本机的服务是采用MFC的socket发的,用C#做客户端,然后客户端启动时,出现该条错误信息 ==通常每个套接字地址(协议/网络地址/端口)只允许使用一次. 笔记的 ...
- jQuary总结1:jQuary的优点和地位
1 什么是jQuery? jQuery是一个快速,小巧,功能丰富的JavaScript库. javascript库: 就是存放javascript代码的仓库 jQuery作为一个迭代多年的优秀框架,是 ...
- javascript总结48:正则表达式(RegExp)
1 正则表达式(英语:Regular Expression) 正则表达式(英语:Regular Expression,在代码中常简写为regex.regexp或RE)使用单个字符串来描述.匹配一系列符 ...