题目描述

在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 首都的更多相关文章

  1. Luogu P4299 首都 LCT

    既然是中文题目,这里便不给题意. 分析: 这个题的做法据说是启发式合并? 但是我不会啊…… 进入正题,LCT是怎样做掉这道题的.记得在前面的一篇<大融合>的题解中,介绍过LCT维护子树信息 ...

  2. P4299 首都

    题目 P4299 首都 做法 这题是动态维护树的重心,连边后找到两棵树的重心拉一条链(性质:新重心在链上),然后暴力爬 要注意: 1.是找重心的过程中要先把旋转标记放下来,因为\(Splay(x)\) ...

  3. 洛谷P4299 首都(BZOJ3510)(LCT,树的重心,二分查找)

    Update:原来的洛谷U21715已成坑qwq 已经被某位管理员巨佬放进公共题库啦!又可以多一个AC记录啦! 洛谷题目传送门 其实也可以到这里交啦 思路分析 动态维护树的重心 题目中说到国家的首都会 ...

  4. [洛谷P4299] 首都

    题目传送门 还是维护子树信息. 但是这里多了一个找重心的操作. 这里有一个关于树重心的结论,据说可以用反证法证明.反正我不会证 就是:新的重心一定在原来两个重心之间的那条树链上. 这样我们逐步缩小搜索 ...

  5. [总结] LCT学习笔记

    \(emmm\)学\(lct\)有几天了,大概整理一下这东西的题单吧 (部分参考flashhu的博客) 基础操作 [洛谷P1501Tree II] 题意 给定一棵树,要求支持 链加,删边加边,链乘,询 ...

  6. [luogu P2521] [HAOI2011]防线修建

    [luogu P2521] [HAOI2011]防线修建 题目描述 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国 ...

  7. Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增)

    Luogu 1084 NOIP2012 疫情控制 (二分,贪心,倍增) Description H 国有 n 个城市,这 n 个城市用 n-1 条双向道路相互连通构成一棵树, 1 号城市是首都, 也是 ...

  8. Luogu 魔法学院杯-第二弹(萌新的第一法blog)

    虽然有点久远  还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题  沉迷游戏,伤感情 #include <queue> ...

  9. luogu p1268 树的重量——构造,真正考验编程能力

    题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...

随机推荐

  1. asp.net mvc area实现多级controller和多级view

    经常需要描述这样的项目结构 ~:. //web根目录├─.admin   //管理员功能目录│  └─index.html    //管理员目录页面├─.user                  / ...

  2. css横线中间放图片或者文字

    效果图: 先贴代码 HTML: <div class="forshow middle"> <div class="flex"></ ...

  3. SQL Server中JOIN的使用方法总结

    JOIN 分为:内连接(INNER JOIN).外连接(OUTER JOIN).其中,外连接分为:左外连接(LEFT OUTER JOIN).右外连接(RIGHT OUTER JOIN).全外连接(F ...

  4. UTC时间、GMT时间、本地时间、Unix时间戳

    引用: https://blog.csdn.net/u012102306/article/details/51538574 https://blog.csdn.net/foxir/article/de ...

  5. 搭建ELK日志分析系统

    看了辣么多博客,就数这个最详细最容易理解了:https://blog.csdn.net/qq_22211217/article/details/80764568 >>>>> ...

  6. javax.validation.ValidationException: Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.

    项目依赖 <dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifa ...

  7. UTF-8编码与GBK编码下的字符长度

    源码: package lsh.java.charset; import java.nio.charset.Charset; public class LengthOfUTF_8 { public s ...

  8. 区分Python中的id()和is以及Python中字符串的intern机制

    参考:1. https://blog.csdn.net/lnotime/article/details/81194633 2.https://segmentfault.com/q/1010000015 ...

  9. mysql对身份证号码进行脱敏处理

    select * from test 格式:INSERT(str,pos,len,newstr) 解释: str:查询的例 pos:起始位置 len:从起始位置开始被后面newstr替换的长度 new ...

  10. 【Python练习题】程序3

    3.题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少?x+100 = n*nx+100+168 = m * m 所以(m+n)*(m-n) =168 #题 ...