[洛谷P4299] 首都
还是维护子树信息。
但是这里多了一个找重心的操作。
这里有一个关于树重心的结论,据说可以用反证法证明。反正我不会证
就是:新的重心一定在原来两个重心之间的那条树链上。
这样我们逐步缩小搜索范围,就可以很快地找到新树的重心了。
另外,每次找重心太慢了,用并查集维护一下每个点所在的树重心。
其他的就没什么特别了。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define id(x) (s[f[x]][1]==x)
using namespace std; int n,m;
int s[][],f[];
int sz[],szi[];
int rev[],rt[];
int ff[]; int findfa(int x)
{
if(x==ff[x])return x;
ff[x]=findfa(ff[x]);
return ff[x];
} void pushup(int p)
{
sz[p]=sz[s[p][]]+sz[s[p][]]+szi[p]+;
} void reverse(int p)
{
swap(s[p][],s[p][]);
rev[p]^=;
} void pushdown(int p)
{
if(!rev[p])return;
reverse(s[p][]);
reverse(s[p][]);
rev[p]=;
} void rotate(int p)
{
int k=id(p);
int fa=f[p];
if(rt[fa])rt[p]=,rt[fa]=;
else s[f[fa]][id(fa)]=p;
s[fa][k]=s[p][!k];
s[p][!k]=fa;
f[p]=f[fa];
f[fa]=p;
f[s[fa][k]]=fa;
pushup(fa);
pushup(p);
} void down(int p)
{
if(!rt[p])down(f[p]);
pushdown(p);
} void splay(int p)
{
down(p);
while(!rt[p])
{
int fa=f[p];
if(rt[fa])
{
rotate(p);
return;
}
if(id(p)^id(fa))rotate(p);
else rotate(fa);
rotate(p);
}
} void access(int p)
{
int son=;
while(p)
{
splay(p);
szi[p]+=sz[s[p][]];
rt[s[p][]]=,rt[son]=;
s[p][]=son;
szi[p]-=sz[s[p][]];
pushup(p);
son=p,p=f[p];
}
} void mtr(int p)
{
access(p);
splay(p);
reverse(p);
} void isolate(int x,int y)
{
mtr(x);
access(y);
splay(y);
} int nueva(int p)
{
int l,r,sum=sz[p]>>,tot=sz[p]&,lsum=,rsum=,ng=n+,nl,nr;
while(p)
{
pushdown(p);
l=s[p][],r=s[p][];
nl=sz[l]+lsum,nr=sz[r]+rsum;
if(nl<=sum&&nr<=sum)
{
if(tot)
{
ng=p;
break;
}else
if(ng>p)ng=p;
}
if(nl<nr)lsum+=sz[l]+szi[p]+,p=r;
else rsum+=sz[r]+szi[p]+,p=l;
}
splay(ng);
return ng;
} int xsum; int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
sz[i]=rt[i]=;
ff[i]=i;
xsum^=i;
}
for(int i=;i<=m;i++)
{
char op[];
scanf("%s",op+);
if(op[]=='A')
{
int x,y;
scanf("%d%d",&x,&y);
isolate(x,y);
f[x]=y;
szi[y]+=sz[x];
pushup(y);
x=findfa(x),y=findfa(y);
isolate(x,y);
int ng=nueva(y);
xsum=xsum^x^y^ng;
ff[x]=ff[y]=ff[ng]=ng;
}
if(op[]=='Q')
{
int x;
scanf("%d",&x);
printf("%d\n",findfa(x));
}
if(op[]=='X')printf("%d\n",xsum);
}
return ;
}
[洛谷P4299] 首都的更多相关文章
- 洛谷P4299 首都(BZOJ3510)(LCT,树的重心,二分查找)
Update:原来的洛谷U21715已成坑qwq 已经被某位管理员巨佬放进公共题库啦!又可以多一个AC记录啦! 洛谷题目传送门 其实也可以到这里交啦 思路分析 动态维护树的重心 题目中说到国家的首都会 ...
- 洛谷4299首都(LCT维护动态重心+子树信息)
这个题目很有意思 QWQ 根据题目描述,我们可以知道,首都就是所谓的树的重心,那么我们假设每颗树的重心都是\(root\)的话,对于每次询问,我们只需要\(findroot(x)\)就可以. 那么如何 ...
- 洛谷P3345 [ZJOI2015]幻想乡战略游戏(动态点分治,树的重心,二分查找,Tarjan-LCA,树上差分)
洛谷题目传送门 动态点分治小白,光是因为思路不清晰就耗费了不知道多少时间去gang这题,所以还是来理理思路吧. 一个树\(T\)里面\(\sum\limits_{v\in T} D_vdist(u,v ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
- 洛谷P1371 NOI元丹
P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交 讨论 题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...
随机推荐
- 装饰器参数加log
#有多个函数,需要计算他们的执行时间,加logimport timedef logger(flag): def show_time(f): #foo对象 def inner(*x,**y): star ...
- Android json数据Log格式化打印
https://blog.csdn.net/adarcy/article/details/76601896 public static final String LINE_SEPARATOR = Sy ...
- IDEA中使用Lombok时候,getter,setter注解不生效/每次重启后才生效
Relevance.java代码如下: import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; imp ...
- 富文本编辑器Tinymce的示例和配置
Demo链接: https://download.csdn.net/download/silverbutter/10557703 有时候需要验证tinyMCE编辑器中的内容是否符合规范(不为空),就需 ...
- 34)static 静态成员和静态成员函数
1) static修饰的方法,只能在这个文件中使用,比如你是多文件编程,别的文件即使引入了我的 .h文件 但那时我的static方法也是不能用 2)C++的static的成员变量 比如 sta ...
- msgfmt - 翻译汉化
说明 目前大部分自由软件实现国际化使用的是gettext. 国际化就是让程序可以使用多国语言来显示程序里的字符串. 程序里一般都有很多字符串,菜单名也好,错误信息也好,都是字符串.假设字符串为stri ...
- javascript获取数组最后一个元素(三种方法)
JavaScript 获取Array末尾元素 一.JavaScript pop() 方法 pop() 方法用于删除并返回数组的最后一个元素. 注意:pop() 方法将删除 arrayObject 的最 ...
- [原]CreateFile中的dwShareMode
原 总结 API 一直对CreateFile的参数dwDesiredAccess和dwShareMode有什么不同不是很清楚,今天重读 windows核心编程的时候终于豁然开朗了. 真是书读百遍,其 ...
- 二十六、linux邮件服务器
1.安装: yum install -y sendmail 因为是最小安装,需要包没有安装 yum install -y mailx 2.日志:/var/log/maillog 3.启动:/etc ...
- JavaMail读取收件箱退信邮件/分析邮件附件获取Message_Id
需求描述:公司最近有个项目邮件通知功能,但是客户上传的邮件地址并不一定存在,以及其他的各种问题.所有希望发送通知后有个回执,及时发现地址存在问题的邮箱. 需求分析:经过分析JavaMail可以读取收件 ...