题目描述

在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[10];
int f[N],ch[N][2],s[N],si[N],fa[N],n,m,st[N],xoR;
bool rev[N];
inline int rd(){int x=0;char c=getchar();bool f=0;while(!isdigit(c)){if(c=='-')f=1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);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]][0]!=x&&ch[fa[x]][1]!=x;}
inline bool ge(int x){return ch[fa[x]][1]==x;}
inline void pushup(int x){s[x]=s[ch[x][0]]+s[ch[x][1]]+si[x]+1;}
inline void pushdown(int x){if(rev[x]){rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;rev[x]^=1;swap(ch[x][0],ch[x][1]); }
}
inline void rotate(int x){int y=fa[x],o=ge(x);if(isroot(x))return;      ch[y][o]=ch[x][o^1];fa[ch[y][o]]=y;if(!isroot(y))ch[fa[y]][ge(y)]=x;fa[x]=fa[y];fa[y]=x;ch[x][o^1]=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=0;x;y=x,x=fa[x]){splay(x);si[x]-=s[y];si[x]+=s[ch[x][1]];ch[x][1]=y;pushup(x); }
}
inline void makeroot(int x){access(x);splay(x);rev[x]^=1;}
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=0,sumr=0,rs,ls,sum=s[x]>>1,o=s[x]&1,now=2e9,xx,yy; while(x){pushdown(x);xx=suml+s[ls=ch[x][0]];yy=sumr+s[rs=ch[x][1]];if(xx<=sum&&yy<=sum){if(o){now=x;break;}else if(x<now)now=x;}if(xx<yy)suml+=s[ls]+si[x]+1,x=rs;else sumr+=s[rs]+si[x]+1,x=ls;}return now;
}
int main(){    n=rd();m=rd();int x,y;for(int i=1;i<=n;++i)s[i]=1,f[i]=i,xoR^=i;    for(int i=1;i<=m;++i){scanf("%s",sh);if(sh[0]=='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[0]=='Q'){x=rd();printf("%d\n",find(x));}else printf("%d\n",xoR); }return 0;
}

转载于:https://www.cnblogs.com/ZH-comld/p/10193648.html

luogu P4299 首都相关推荐

  1. Luogu P4299 首都 LCT

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

  2. P4299 首都(LCT、重心)

    解析 动态维护树的重心 关键性质:两棵树合并时,新的重心一定在两个原重心之间的路径上 把两个重心之间的路径提出来,利用splay本身的二叉结构二分即可 注意虚子树信息的处理 不要忘记pushdown ...

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

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

  4. luogu P1549 棋盘问题(2) 题解

    luogu P1549 棋盘问题(2) 题解 题目描述 在\(N * N\)的棋盘上\((1≤N≤10)\),填入\(1,2,-,N^2\)共\(N^2\)个数,使得任意两个相邻的数之和为素数. 例如 ...

  5. [Luogu] 选学霸

    https://www.luogu.org/problemnew/show/P2170 并查集+DP #include <iostream> #include <cstring> ...

  6. Luogu 2470 [SCOI2007]压缩

    和Luogu 4302 [SCOI2003]字符串折叠 差不多的想法,区间dp 为了计算方便,我们可以假设区间[l, r]的前面放了一个M,设$f_{i, j, 0/1}$表示区间$[i, j]$中是 ...

  7. 【Luogu】P1613 跑路

    [Luogu]P1613 跑路 一.题目 题目描述 小A的工作不仅繁琐,更有苛刻的规定,要求小A每天早上在6:00之前到达公司,否则这个月工资清零.可是小A偏偏又有赖床的坏毛病.于是为了保住自己的工资 ...

  8. Luogu P6055 [RC-02] GCD(莫比乌斯反演,杜教筛)(这题乐死我了,真就图一乐呗)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Weblink https://www.luogu.com.cn/problem/P6055 Prob ...

  9. Luogu P3177 [HAOI2015] 树上染色(树上背包)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Luogu P3177 [HAOI2015] 树上染色 有一棵点数为 NNN 的树,树边有边权.给你一 ...

最新文章

  1. iPhone UITextField-更改占位符文本颜色
  2. EasyUI学习总结(五)——EasyUI组件使用
  3. http request乱码的真相
  4. 2020-10-27(补码10000000为什么可以表示-128?)
  5. 2021牛客多校2 - Girlfriend(球体积交)
  6. 如何在centos安装python3.4
  7. android 设置线程优先级
  8. 数据库连接池优化配置(druid,dbcp,c3p0)
  9. EasyRecovery解救打工人的崩溃
  10. redies的复习总结
  11. 亲爱的热爱的百度云全集资源
  12. python语义分析_Python自然语言分析
  13. 打开Beyond Compare报This license key has been revoked:
  14. 每日刷题:lightoj-1004 - Monkey Banana Problem
  15. 几何光学学习笔记(2)- 1.2 费马原理、马吕斯定律和成像
  16. 使用Python的PyPD创建PDF文档
  17. 科技云报道:华为云数据灾备,守护企业的生命线
  18. mysql数据库锁 栅栏,如何使用MySQL查找多边形地理围栏中包含的点
  19. 手推提升算法之AdaBoost
  20. Python第三方库tabulate简单使用说明

热门文章

  1. 俄罗斯钓鱼四服务器未响应,俄罗斯钓鱼4《RussianFishing4》sbirolino钓组攻略
  2. 【Excel】excel使用VLOOKUP+IF实现多列匹配查找
  3. “海底数据中心”被打捞出水,故障率仅为陆地1/8;京东超大规模联邦学习平台开源...
  4. 券商API/程序化交易接口
  5. node-red教程6 串口控件的使用
  6. C++之命令(Command)模式
  7. 【知识产权基础之专利权】第一章 专利权的客体
  8. 直到黎明 Until Dawn 后感
  9. 机器学习入门要学习什么内容呢?
  10. Java实现一个订餐外卖系统