BZOJ3510首都(LCT)
Description
在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:询问当前所有国家首都编号的异或和。
Input
第一行是整数N,M,表示城市数和需要处理的信息数。
接下来每行是一个信息,格式如题目描述(A、Q、Xor中的某一种)。
Output
输出包含若干行,为处理Q和Xor信息的结果。
Sample Input
Xor
Q 1
A 10 1
A 1 4
Q 4
Q 10
A 7 6
Xor
Q 7
Xor
Sample Output
11
1
1
1
2
6
2
解题思路:
主要是动态维护重心。
可以证明,新的中心在原来两个树中心路径上。
那么就把这段路径提取出来找就好了。
注意将重心旋转至根,保证时间复杂度。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lll tr[spc].ch[0]
#define rrr tr[spc].ch[1]
#define ls ch[0]
#define rs ch[1]
struct trnt{
int ch[];
int fa;
int lzt;
int wgt;
int wgti;
int ff;
bool anc;
}tr[];
int st[];
int tp;
int n,m;
int Xorsum;
char cmd[];
bool whc(int spc)
{
return tr[tr[spc].fa].rs==spc;
}
int finf(int x)
{
return tr[x].ff==x?x:tr[x].ff=finf(tr[x].ff);
}
void pushup(int spc)
{
if(!spc)
return ;
tr[spc].wgt=tr[spc].wgti+tr[lll].wgt+tr[rrr].wgt+;
return ;
}
void trr(int spc)
{
if(!spc)
return;
std::swap(lll,rrr);
tr[spc].lzt^=;
return ;
}
void pushdown(int spc)
{
if(tr[spc].lzt)
{
trr(lll);
trr(rrr);
tr[spc].lzt=;
}
return ;
}
void recal(int spc)
{
if(!tr[spc].anc)
recal(tr[spc].fa);
pushdown(spc);
return ;
}
void rotate(int spc)
{
int f=tr[spc].fa;
bool k=whc(spc);
tr[f].ch[k]=tr[spc].ch[!k];
tr[spc].ch[!k]=f;
if(tr[f].anc)
{
tr[spc].anc=;
tr[f].anc=;
}else
tr[tr[f].fa].ch[whc(f)]=spc;
tr[spc].fa=tr[f].fa;
tr[f].fa=spc;
tr[tr[f].ch[k]].fa=f;
pushup(f);
pushup(spc);
return ;
}
void splay(int spc)
{
recal(spc);
while(!tr[spc].anc)
{
int f=tr[spc].fa;
if(tr[f].anc)
{
rotate(spc);
break;
}
if(whc(spc)^whc(f))
rotate(spc);
else
rotate(f);
rotate(spc);
}
return ;
}
void access(int spc)
{
int lst=;
while(spc)
{
splay(spc);
tr[spc].wgti+=tr[rrr].wgt;
tr[spc].wgti-=tr[lst].wgt;
tr[rrr].anc=;
tr[lst].anc=;
rrr=lst;
pushup(spc);
lst=spc;
spc=tr[spc].fa;
}
return ;
}
void Mtr(int spc)
{
access(spc);
splay(spc);
trr(spc);
return ;
}
void split(int x,int y)
{
Mtr(x);
access(y);
splay(y);
return ;
}
void link(int x,int y)
{
split(x,y);
tr[x].fa=y;
tr[y].wgti+=tr[x].wgt;
pushup(y);
return ;
}
int Gravity(int spc)
{
int lwgt=;
int rwgt=;
int tot=tr[spc].wgt/;
int odd=tr[spc].wgt&;
int ans=0x3f3f3f3f;
while(spc)
{
pushdown(spc);
int ll,rr;
ll=lwgt+tr[lll].wgt;
rr=rwgt+tr[rrr].wgt;
if(ll<=tot&&rr<=tot)
{
if(odd)
{
ans=spc;
break;
}
if(ans>spc)
ans=spc;
}
if(ll>rr)
{
rwgt+=(tr[spc].wgti+tr[rrr].wgt+);
spc=lll;
}else{
lwgt+=(tr[spc].wgti+tr[lll].wgt+);
spc=rrr;
}
}
splay(ans);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
tr[i].wgt=tr[i].anc=;
tr[i].ff=i;
Xorsum^=i;
}
while(m--)
{
scanf("%s",cmd);
if(cmd[]=='A')
{
int x,y;
scanf("%d%d",&x,&y);
link(x,y);
x=finf(x);
y=finf(y);
split(x,y);
int g=Gravity(y);
Xorsum=Xorsum^x^y^g;
tr[x].ff=tr[y].ff=tr[g].ff=g;
}
if(cmd[]=='Q')
{
int x;
scanf("%d",&x);
printf("%d\n",finf(x));
}
if(cmd[]=='X')
{
printf("%d\n",Xorsum);
}
}
return ;
}
BZOJ3510首都(LCT)的更多相关文章
- bzoj3510 首都 LCT 维护子树信息+树的重心
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3510 题解 首先每一个连通块的首都根据定义,显然就是直径. 然后考虑直径的几个性质: 定义:删 ...
- 【BZOJ3510】首都 LCT维护子树信息+启发式合并
[BZOJ3510]首都 Description 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打 ...
- 【bzoj3510】首都 LCT维护子树信息(+启发式合并)
题目描述 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失, ...
- BZOJ3510 首都(LCT)
即动态维护树的重心.考虑合并后的新重心一定在两棵树的重心的连线上.于是对每个点维护其子树大小,合并时在这条链的splay上二分即可.至于如何维护子树大小,见https://blog.csdn.net/ ...
- BZOJ3510 首都
题目描述 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失, ...
- Bzoj3510首都
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...
- BZOJ.3510.首都(LCT 启发式合并 树的重心)
题目链接 BZOJ 洛谷 详见这. 求所有点到某个点距离和最短,即求树的重心.考虑如何动态维护. 两棵子树合并后的重心一定在两棵树的重心之间那条链上,所以在合并的时候用启发式合并,每合并一个点检查sz ...
- Luogu P4299 首都 LCT
既然是中文题目,这里便不给题意. 分析: 这个题的做法据说是启发式合并? 但是我不会啊…… 进入正题,LCT是怎样做掉这道题的.记得在前面的一篇<大融合>的题解中,介绍过LCT维护子树信息 ...
- BZOJ 3510: 首都 LCT + multiset维护子树信息 + 树的重心
Code: #include<bits/stdc++.h> #define maxn 200000 #define inf 1000000000 using namespace std; ...
随机推荐
- js插件---瀑布流Masonry
js插件---瀑布流Masonry 一.总结 一句话总结:还是要去看官网,比amazeui上面介绍的详细很多 1.瀑布流的原理是什么? 给外层套好相对定位,里面的每一个弄好绝对定位,然后计算出每一个的 ...
- input file HTML控件控制
网页上添加一个input file HTML控件: 1 <input id="File1" type="file" /> 默认是这样的,所有文件类型 ...
- javascript学习笔记总结
1 有些浏览器可能不支持JavaScript,我们可以使用如下的方法对它们隐藏JavaScript代码. <html> <body> <script type=" ...
- openSUSE Leap与 SELS的区别
openSUSE Leap 是 openSUSE 常规发行版本的新名称,在 13.2 之前它仅仅被称为“openSUSE”. 一.openSUSE 发行周期:(15年以前仅有一个openSUSE发行版 ...
- weex入门(一)
emmmm其实没有接触过weex ,了解一番发现有很多坑,有很多基于weex改良后的框架,比如weexplus等等,基本不用踩多少坑.经过几天的深思熟虑我觉得还是去踩坑,毕竟踩完坑才能真正的了解嘛 w ...
- 客户端本地存储(cookie、web Storage、vuex)选择
一.cookie .localStorage .sessionStorage .vuex 比较 cookie 4K 有时效性 可服务器传递 cookie是由服务器产生,存储在客户端的一 ...
- tac---反转输出文件
tac命令用于将文件已行为单位的反序输出,即第一行最后显示,最后一行先显示.
- Python 面向对象 —— super 的使用(Python 2.x vs Python 3.x)
注意区分当前的 Python 版本是 2.X 还是 3.X,Python 3.X 在 super 的使用上较之 Python 2.X 有较大的变化: 1. Python 2.x class Conta ...
- POJ 3168 排序+扫描
题意: 思路: 我们可以把每个矩形拆成四条线 与x轴平行的放在一起 与y轴平行的放在一起 排个序 判一判有没有交 有交 则说明不可扩张 统计一下 就可以了 处理的姿势很重要 姿势不对毁一生 //By ...
- arp---操作主机的arp缓冲区
简介 arp命令用于操作主机的arp缓冲区,可以用来显示arp缓冲区中的所有条目.删除指定的条目或者添加静态的ip地址与MAC地址对应关系. 选项 -a<主机>:显示arp缓冲区的所有条目 ...