BZOJ4855 : [Jsoi2016]轻重路径
首先用树状数组维护dfs序来快速支持一个点子树大小的询问。
每次删掉一个叶子时,从根开始往叶子走,显然只有$2size[x]\leq size[father]$的点的父亲才有可能换重儿子。
从根开始往下,找到最高的满足条件的点,从那个点开始继续迭代,每次点数至少减小一半,所以迭代只有$O(\log n)$次。
时间复杂度$O(n\log^2n)$。
#include<cstdio>
const int N=200010;
int n,m,x,i,ch[N][2],size[N],f[N],d[N],son[N],top[N],st[N],en[N],q[N],dfn,bit[N];long long ans;
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
inline void add(int x,int p){for(;x<=n;x+=x&-x)bit[x]+=p;}
inline int ask(int x){int t=0;for(;x;x-=x&-x)t+=bit[x];return t;}
inline int getsize(int x){if(!x)return 0;return ask(en[x])-ask(st[x]-1);
}
void dfs(int x){size[x]=1;for(int i=0;i<2;i++){int y=ch[x][i];if(!y)continue;f[y]=x;d[y]=d[x]+1;dfs(y),size[x]+=size[y];if(size[y]>size[son[x]])son[x]=y;}ans+=son[x];
}
void dfs2(int x,int y){q[st[x]=++dfn]=x;top[x]=y;if(son[x])dfs2(son[x],y);for(int i=0;i<2;i++){int o=ch[x][i];if(!o||o==son[x])continue;dfs2(o,o);}en[x]=dfn;
}
inline int up(int x,int k){while(1){if(st[x]-st[top[x]]>=k)return q[st[x]-k];k-=st[x]-st[top[x]]+1;x=f[top[x]];}
}
inline void recal(int x){if(!x)return;ans-=son[x];int t=0;for(int i=0;i<2;i++){int y=ch[x][i],w=getsize(y);if(w>t)t=w;}if(!t)son[x]=0;else if(getsize(son[x])!=t){if(getsize(ch[x][0])==t)son[x]=ch[x][0];else son[x]=ch[x][1];}ans+=son[x];
}
inline void remove(int x){add(st[x],-1);int lim=d[x],o=lim;while(1){int l=1,r=o,mid,t=0,s=getsize(up(x,o));while(l<=r)if(getsize(up(x,mid=(l+r)>>1))*2<=s)l=(t=mid)+1;else r=mid-1;recal(f[up(x,t)]);if(!o)return;o=t;}
}
int main(){while(~scanf("%d",&n)){if(!n)return 0;for(dfn=ans=0,i=1;i<=n;i++)size[i]=son[i]=bit[i]=0;for(i=1;i<=n;i++)read(ch[i][0]),read(ch[i][1]);dfs(1);dfs2(1,1);printf("%lld\n",ans);for(i=1;i<=n;i++)add(i,1);for(read(m);m--;printf("%lld\n",ans))read(x),remove(x);}return 0;
}
BZOJ4855 : [Jsoi2016]轻重路径相关推荐
- 【GDOI2016模拟4.22】总结
前言 早上,一进机房,发现所有人神情严肃,一股(\(da\))(\(ba\))场的气氛迎面扑来,我一下子意识到:nothing good! 这场比赛结果不是很好,50分: 第一题:感觉上是个神奇的匹配 ...
- [NOI2021 day1]轻重边(树链剖分),路径交点(矩阵行列式)
NOI 2021 day1 轻重边 description solution code 路径交点 description solution code 轻重边 description solution ...
- 【路径规划】基于遗传算法实现外卖订单动态变换模型求解附matlab代码
1 内容介绍 前瞻产业研究院发布的<中国在线外卖商业模式与投资战略规划分析报告>统计数据显示,2015-2018年中国在线外卖收入年均增速约为117.5%,是传统餐饮业的12.1倍,我国在 ...
- 临床路径实施难点探讨
临床路径信息系统实施难点探讨 近年来,医疗卫生服务水平得到持续提高,各项高新技术不断开展:随之而来的是,医疗卫生费用迅猛上涨.如何有效利用现有资源,在控制医疗费用的同时规范医疗服务,保证质量,是目前卫 ...
- 伍六七带你学算法 动态规划 ——不同路径
力扣 62. 不同路径 难度 中等 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格 ...
- Go 语言同一个包内函数调用、包名和实际路径最后一个目录不一致问题
以下代码的 GOPATH 路径为 "/home/wohu/GoCode" 1. 同一个包内的函数可以相互调用 代码结构如下: wohu@wohu:~/GoCode/src$ tre ...
- Python 标准库之 os (获取当前目录、读取/设置环境变量、重命名文件、运行shell命令、创建/删除/查看目录文件、判断目录/文件/存在、获取绝对路径、获取文件名、获取换行符、获取路径分隔符)
1. os与sys模块的官方解释如下: os This module provides a portable way of using operating system dependent funct ...
- 二叉树中和为某一值的路径
前言 输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径.(注意: 在返回值的list中,数组长度大的数 ...
- 获取当前脚本目录路径问题汇总
20211223 https://blog.csdn.net/qq_43178297/article/details/88053836 获取上一层目录 import osprint('***获取当前目 ...
最新文章
- php localcompare,GetDriveName 方法
- 国际运营商智慧城市探索与实践
- 99%的人都会用错或者不会看的N折验证
- 4.RabbitMQ 4种交换模式
- 版本控制软件Visual Source safe使用小结 (配合上文)
- VMware下的ubuntu12.04不识别usb设备问题的解决方法
- html5鼠标讯听,HTML5 随鼠标移动而变化的低频信号发生器
- RedisHelper帮助类
- Stacking:Catboost、Xgboost、LightGBM、Adaboost、RF etc
- 黄金分割法与单峰函数求极值
- Docker容器-cgroups资源配置
- 50个高端大气上档次的管理后台界面模板
- opengGL实战——太阳系三维场景动画搭建
- 百度信息流是什么?哪些行业适合投放百度信息流?
- [USACO12MAR]花盆Flowerpot(二分答案+单调队列)
- 完整创建 注册功能步骤
- FakeApp下载及教程
- 笔记本计算机涂硅脂,硅脂,小编教你怎么在电脑CPU上涂散热硅脂
- 【Luogu P4766】 [CERC2014]Outer space invaders(区间dp)
- 大学高校供配电系统谐波危害及治理方案
热门文章
- 软考-信息系统项目管理师-战略管理
- 集成学习(ensemble learning)(二)
- Dart_VM的相关简介与运行模式解析
- admob 服务器验证_AdMob服务器注册广告请求,但Ad对象包含“必须声明AdActivity”错误...
- 神策数据《品牌零售业数字化运营的方法论及实践》白皮书重磅发布
- 直播预告丨深耕用户价值,实战保险业数字化升级
- PPT 下载 | 数据治理中的一些挑战与应用
- 第一期赠书活动《硅谷百年史》已寄出
- Linux脚本 输入90为优秀
- Flutter React编程范式实践