BZOJ权限题。

洛谷

题目描述

在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:询问当前所有国家首都编号的异或和。

Sol

就是让你动态维护重心 , 但只有加边操作。

重心的一个性质 , 当加入一个叶子节点后 , 重心最多移动一条边的距离。

而判断一个点是否是重心 , 只需要判断它的各儿子的子树大小是否超过整棵树大小一半即可。

所以有一个暴力做法 , 启发式合并 , 然后判断重心是否移动即可。

复杂度\(O(nlog^2n)\)

更加优秀的做法:

重心还有个性质 , 合并两棵树 , 新的重心一定在原来两个重心的路径上 。

那么我们用 \(LCT\) 把路径抠出来 , 重心的位置是可以二分出来的。

具体来说 , 我们在 \(Splay\) 上走 , 每次把两边的 \(size\) 维护好然后判断最大子树大小就行了

注意这里并不需要关心虚子树大小 , 简单来理解就是重心会往大的子树方向动 , 但是合并两棵子树后重心在路径上 , 所以不用关心原来的子树。严格一点分析 , 由于原来那些子树大小不超过原来大小的一半 , 自然不会超过现在大小的一半 。

code:

#include<bits/stdc++.h>
using namespace std;
template<class T>inline void init(T&x){
x=0;char ch=getchar();bool t=0;
for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') t=1;
for(;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+(ch-48);
if(t) x=-x;
}
const int N(1e5+10);
int n,m;
#define ls son[0]
#define rs son[1]
#define __ NULL
#define get_son(a) (a->fa->rs==a)
#define get(a,b,c) (a? a->b:c)
#define IS(a) (a&&(!a->fa||(a->fa->son[get_son(a)]!=a))) struct node{
node*son[2],*fa;int size,cnt;bool rev;
node(){ls=rs=fa=__,size=cnt=1;rev=0;}
}T[N],*stk[N];int top=0;
inline void update(node*p){if(!p)return;p->size=get(p->ls,size,0)+get(p->rs,size,0)+p->cnt;}
inline void rotate(node*p){
int k=get_son(p);node*q=p->fa,*gp=p->fa->fa;
q->son[k]=p->son[k^1];
if(p->son[k^1]) p->son[k^1]->fa=q;
if(!IS(q)) gp->son[get_son(q)]=p;
p->fa=gp,q->fa=p,p->son[k^1]=q;
return update(q);
}
inline void push_down(node*p){
if(!p||!p->rev)return;swap(p->ls,p->rs);p->rev=0;
if(p->ls)p->ls->rev^=1;if(p->rs) p->rs->rev^=1;
return;
}
inline void Push(node*p){
stk[top=1]=p;while(!IS(p)) p=p->fa,stk[++top]=p;
while(top) push_down(stk[top--]);return;
}
inline void Splay(node*p){
if(!p)return;Push(p);
for(;!IS(p);rotate(p)) if(IS(p->fa)) continue;else get_son(p->fa)==get_son(p)? rotate(p->fa):rotate(p);
return update(p);
}
inline void access(node*p){node*pre=__;for(;p;pre=p,p=p->fa)Splay(p),p->cnt+=get(p->rs,size,0)-get(pre,size,0),p->rs=pre,update(p);}
inline void make_root(node*p){access(p);Splay(p);p->rev^=1;}
inline void split(node*p,node*q){make_root(p),access(q),Splay(q);return;}
inline void link(node*p,node*q){split(p,q);p->fa=q;q->cnt+=p->size,update(q);return;}
inline void cut(node*p,node*q){split(p,q);if(q->ls==p) p->fa=q->ls=__,update(q);return;}
inline node* Find(node*p){access(p);Splay(p);while(p->ls)p=p->ls;return p;}
inline int WP(int u){return (int)(Find(&T[u])-T);}
#define ID(a) ((a)-T)
int Xor,TOT;
inline void Solve(node*p,node*q) {
split(p,q);node*u=q;node*Ne=__;
int ban=TOT>>1;
int suml=0,sumr=0;
int nowl,nowr;
while(u) {
push_down(u);
node*L=u->ls,*R=u->rs;
nowl=suml+get(L,size,0),nowr=sumr+get(R,size,0);
if(nowl<=ban&&nowr<=ban) {
if(TOT&1) {Ne=u;break;}
else if((!Ne)||ID(Ne)>ID(u)) Ne=u;
}
if(nowl>=nowr) sumr+=get(R,size,0)+u->cnt,u=L;
else suml+=get(L,size,0)+u->cnt,u=R;
}
make_root(Ne);Xor^=ID(Ne);
}
int main()
{
init(n),init(m);
int u,v;for(int i=1;i<=n;++i) Xor^=i;
for(int i=1;i<=m;++i) {
char ch=getchar();while(ch!='A'&&ch!='Q'&&ch!='X') ch=getchar();
if(ch=='A') {
init(u),init(v);
int x=WP(u),y=WP(v);
Splay(&T[x]),Splay(&T[y]);
TOT=T[x].size+T[y].size;
Xor^=x^y;link(&T[u],&T[v]);
Solve(&T[x],&T[y]);
}
else if(ch=='Q') {init(u);printf("%d\n",WP(u));}
else if(ch=='X') printf("%d\n",Xor);
}
}

【Luogu4299】首都的更多相关文章

  1. luogu P4299 首都

    题目描述 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失, ...

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

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

  3. Java各国首都列表

    国 家 名 称 首  都 中华人民共和国 People's Republic of China 北京 Beijing 蒙古 Mongolia 乌兰巴托 Elggydggmgj 朝鲜 Democrati ...

  4. 首都医科大学附属北京安贞医院全院级PACS系统采购项目[转]

    项目名称:首都医科大学附属北京安贞医院全院级PACS系统采购项目 项目编号:TC140VCF0 采购人名称:首都医科大学附属北京安贞医院 采购人地址:北京市朝阳区安贞里 采购人联系方式:010-644 ...

  5. BZOJ3510 首都

    题目描述 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失, ...

  6. 【刷题】BZOJ 3510 首都

    Description 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从 ...

  7. 【bzoj3510】首都 LCT维护子树信息(+启发式合并)

    题目描述 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打败了B国,那么B国将永远从这个星球消失, ...

  8. P4299 首都

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

  9. 【BZOJ3510】首都 LCT维护子树信息+启发式合并

    [BZOJ3510]首都 Description 在X星球上有N个国家,每个国家占据着X星球的一座城市.由于国家之间是敌对关系,所以不同国家的两个城市是不会有公路相连的. X星球上战乱频发,如果A国打 ...

随机推荐

  1. docker windows下挂载目录和文件

    我们利用docker启动项目的时候不能直接修改容器中的内容,只能在  run  的时候挂载到本地目录或者文件来进行修改. 例子:(路径可以忽略斜杠和反斜杠,我这边使用windows的路径没有报错.do ...

  2. LeetCode算法题-Goat Latin Easy(Java实现)

    这是悦乐书的第322次更新,第344篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第192题(顺位题号是824).给出句子S,由空格分隔的单词组成.每个单词仅由小写和大写 ...

  3. 深入理解java:1.1. 类加载器

    从java的动态性到类加载机制   我们知道,Java是一种动态语言. 那么怎样理解这个“动态”呢? 或者说一门语言具备了什么特性,才能称之为动态语言呢? 对于java,我是这样理解的. 我们都知道J ...

  4. (4.24)【mysql、sql server】分布式全局唯一ID生成方案

    参考:分布式全局唯一ID生成方案:https://blog.csdn.net/linzhiqiang0316/article/details/80425437 分表生成唯一ID方案 sql serve ...

  5. mysql日志信息查看与设置mysql-bin

    查看 sql查询记录  日志是否开启 SHOW GLOBAL VARIABLES LIKE '%general_log%' 二进制日志 是否开启 SHOW GLOBAL VARIABLES LIKE ...

  6. Java - PhantomJS + EChartsConvert实现ECharts图片保存到服务端

    1.所需工具 1>phantomjs:官网下载http://phantomjs.org/download.html 国内镜像http://npm.taobao.org/dist/phantomj ...

  7. Vue 实现手动刷新组件

    Vue 实现手动刷新组件:https://www.jianshu.com/p/742142dc95f3

  8. [BZOJ4444] [Luogu 4155] [LOJ 2007] [SCOI2015]国旗计划(倍增)

    [BZOJ4444] [Luogu 4155] [LOJ 2007] [SCOI2015]国旗计划(倍增) 题面 题面较长,略 分析 首先套路的断环为链.对于从l到r的环上区间,若l<=r,我们 ...

  9. 思维体操: HDU1049Climbing Worm

    Climbing Worm Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  10. 异步Promise及Async/Await可能最完整入门攻略

    此文只介绍Async/Await与Promise基础知识与实际用到注意的问题,将通过很多代码实例进行说明,两个实例代码是setDelay和setDelaySecond. tips:本文系原创转自我的博 ...