Discription:

断开树的每一个点会形成一个森林,然后可以进行一次操作:将森林中的一棵树接到另一棵树上。使得森林中size最大的树size最小。依次输出对于每个结点的最小size值

Hint:

\(n<=1e5\)

Solution:

用multiset维护每个点的size域,每次贪心将最大的树的子树接到最小的树上,答案用二分答案求出

本题细节较多,需要处理各种情况

#include<bits/stdc++.h>
using namespace std;
typedef multiset<int >::iterator mit;
const int mxn=1e5+5;
struct ed {
int to,nxt;
}t[mxn];
int n,rt,cnt;
int hd[mxn],sz[mxn],f[mxn],son[mxn],ans[mxn];
multiset<int >mp[mxn],oth,anc; inline void add(int u,int v) {
t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
} void dfs1(int u)
{
sz[u]=1;
for(int i=hd[u];i;i=t[i].nxt) {
int v=t[i].to;
dfs1(v); sz[u]+=sz[v];
if(sz[v]>sz[son[u]]) son[u]=v;
}
if(u!=rt) oth.insert(sz[u]);
} //第一遍Dfs预处理出重儿子和初始size inline int check(int opt,int val,int u,int mi,int mx)
{
if(opt) {
mit tp=mp[son[u]].lower_bound(mx-val);
if(tp!=mp[son[u]].end()&&(*tp)+mi<=val) return 1;
}
else {
mit tp=oth.lower_bound(mx-val);
if(tp!=oth.end()&&(*tp)+mi<=val) return 1;
tp=anc.lower_bound(mx-val+sz[u]);
if(tp!=anc.end()&&(*tp)+mi-sz[u]<=val) return 1;
}
return 0;
} //分类讨论检验答案 void dfs2(int u)
{
if(u!=rt) oth.erase(oth.lower_bound(sz[u])); //一开始删除,后面会加进来
if(f[u]&&f[u]!=rt) anc.insert(sz[f[u]]);
//因为祖先size是变化的,故将祖先单独拿出来维护
int mx1=max(n-sz[u],sz[son[u]]); //子树size的最大值
int mx2=min(n-sz[u],sz[son[u]]); //子树size的次大值
int mi=n-sz[u]; //子树size的最小值
if(!mi) mi=sz[son[u]];
for(int i=hd[u];i;i=t[i].nxt) {
int v=t[i].to;
if(v==son[u]) continue ;
dfs2(v);
for(mit it=mp[v].begin();it!=mp[v].end();++it)
oth.insert(*it);
mi=min(mi,sz[v]),mx2=max(mx2,sz[v]);
}
if(son[u]) dfs2(son[u]),mi=min(mi,sz[son[u]]);
for(int i=hd[u];i;i=t[i].nxt) {
int v=t[i].to;
if(v==son[u]) continue ;
for(mit it=mp[v].begin();it!=mp[v].end();++it)
oth.erase(oth.lower_bound(*it));
}
if(mx1!=mx2) {
int l=mx2,r=mx1;
int opt=(mx1==sz[son[u]]);
while(l<=r) {
int mid=(l+r)>>1;
if(check(opt,mid,u,mi,mx1)) ans[u]=mid,r=mid-1;
else l=mid+1;
}
} //当操作有意义时,二分答案
if(!ans[u]) ans[u]=mx1;
if(son[u]) swap(mp[u],mp[son[u]]);
//每次直接O(1)继承重儿子的set,从而保证了时间复杂度 for(int i=hd[u];i;i=t[i].nxt) {
int v=t[i].to;
if(v==son[u]) continue ;
for(mit it=mp[v].begin();it!=mp[v].end();mp[v].erase(it++))
mp[u].insert(*it);
}
if(f[u]&&f[u]!=rt) anc.erase(anc.lower_bound(sz[f[u]]));
mp[u].insert(sz[u]);
} void solve()
{
dfs2(rt);
for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
} int main()
{
int u,v;
scanf("%d",&n);
for(int i=1;i<=n;++i) {
scanf("%d %d",&u,&v);
if(!u) rt=v;
else add(u,v),f[v]=u;
}
dfs1(rt); solve();
return 0;
}

[CF768G] The Winds of Winter的更多相关文章

  1. 【CF768G】The Winds of Winter 可持久化线段树 DFS序

    题目大意 给定一棵\(n\)个点的树,对于树上每个结点,将它删去,然后可以将得到的森林中任意一个点与其父亲断开并连接到另一颗树上,对每一个点求出森林中所有树\(size\)最大值的最小值. \(n\l ...

  2. Winter Storm Warning

    2019-01-02 11:22:33 ...WINTER STORM WARNING REMAINS IN EFFECT UNTIL 6 AM AKST TUESDAY... * WHAT...He ...

  3. 开发框架Data Abstract和Hydra发布版本Winter 2013

    Data Abstract Winter 2013即Data Abstract Version 7.0.73 (Build .1111),Winter 2013版对Data Abstract继续做了以 ...

  4. 2015 UESTC Winter Training #10【Northeastern Europe 2009】

    2015 UESTC Winter Training #10 Northeastern Europe 2009 最近集训都不在状态啊,嘛,上午一直在练车,比赛时也是刚吃过午饭,状态不好也难免,下次比赛 ...

  5. 2015 UESTC Winter Training #8【The 2011 Rocky Mountain Regional Contest】

    2015 UESTC Winter Training #8 The 2011 Rocky Mountain Regional Contest Regionals 2011 >> North ...

  6. 2015 UESTC Winter Training #7【2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest】

    2015 UESTC Winter Training #7 2010-2011 Petrozavodsk Winter Training Camp, Saratov State U Contest 据 ...

  7. 2015 UESTC Winter Training #6【Regionals 2010 >> North America - Rocky Mountain】

    2015 UESTC Winter Training #6 Regionals 2010 >> North America - Rocky Mountain A - Parenthesis ...

  8. 2015 UESTC Winter Training #4【Regionals 2008 :: Asia - Tehran】

    2015 UESTC Winter Training #4 Regionals 2008 :: Asia - Tehran 比赛开始时电脑死活也连不上WIFI,导致花了近1个小时才解决_(:зゝ∠)_ ...

  9. winds引导配置数据文件包含的os项目无效

    我装了winds7与linux双系统,用easyBcd程序时,删除了一个winds7,之后winds7就进不去了, 进入winds7时显示winds未能启动,原因可能是最近更改了硬件或软件.解决此问题 ...

随机推荐

  1. AI-序列化-做五个数据接口

    #url.py url(r'^customer/$', views.CustomerView.as_view()), #查询所有数据.添加数据接口url url(r'^customer/(\d+)', ...

  2. 阿里云人脸识别测试接口出错 返回Body:{ "errno": 1031, "err_msg": "Invalid Image URL.", "request_id": "cdbe2927-e1bb-4eb1-a603-8fcd4b0b7fc8" }

    错误信息如下 返回Body:{ "errno": 1031, "err_msg": "Invalid Image URL.", " ...

  3. Vs2015 本地git获取的代码目录文件修改后,启动提示error:Unable to start program “C:\Program Files\dotnet\dotnet.exe” 已解决.

    http://stackoverflow.com/questions/39938453/unable-to-start-program-c-program-files-dotnet-dotnet-ex ...

  4. Python Web开发问题收集(二)

  5. Linux拷贝U盘文件(命令行)

    Linux系统有的有界面,有的没有只要命令窗口,因此导入外部文件就变得困难,没有可视化的方便. 这里通过挂载u盘进行文件拷贝. 首先挂载u盘:这里以centos为例 1.进入命令行模式下,输入命令 s ...

  6. selenium_webdriver(python)控制浏览器滚动条

    调过JS脚本控制 #coding=utf-8 from selenium import webdriver import time #访问百度 driver=webdriver.Firefox() d ...

  7. Java中常见的排序方式-选择排序(升序)

    [基本思想] 假设数组为int[] a = { 49, 38, 65, 97, 76, 13, 27 },数组元素个数为7个. 第1轮比较:先是a[0]与a[1]比较,大于则先交换,再比较a[0]和a ...

  8. kafka工作流程| 命令行操作

    1.  概述 数据层:结构化数据+非结构化数据+日志信息(大部分为结构化) 传输层:flume(采集日志--->存储性框架(如HDFS.kafka.Hive.Hbase))+sqoop(关系型数 ...

  9. 不同路径(一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。 问总共有多少条不同的路径?)

    示例 1: 输入: m = 3, n = 2 输出: 3 解释: 从左上角开始,总共有 3 条路径可以到达右下角. 1. 向右 -> 向右 -> 向下 2. 向右 -> 向下 -&g ...

  10. Trident中的解析包含的函数操作与投影操作

    一:函数操作 1.介绍 Tuple本身是不可变的 Function只是在原有的基础上追加新的tuple 2.说明 如果原来的字段是log,flag 新增之后的tuple可以访问这些字段,log,fla ...