首先用树状数组维护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;
}

  

最新文章

  1. Httpoxy远程代理感染漏洞 [转]
  2. ExtJS笔记3 MVC Architecture
  3. easyui-datebox 只显示年月
  4. JavaScript表单编程
  5. c\c++ 字符串处理大集合[转]
  6. (qsf文件 、 tcl文件 和 csv(txt)文件的区别) FPGA管脚分配文件保存、导入导出方法
  7. (转)Java爬虫,信息抓取的实现
  8. 为什么不使用frame框架的原因
  9. POJO概念
  10. window.open的小技巧分享(转)
  11. Windows 小端存储
  12. 记录一次网站漏洞修复过程(三):第二轮处理(拦截SQL注入、跨站脚本攻击XSS)
  13. [洛谷P2627] 修剪草坪
  14. json文件解析
  15. Codeforces 1062 - A/B/C/D/E - (Undone)
  16. 从零开始一起学习SLAM | 给点云加个滤网
  17. oracle中常见的对表、表空间和视图的操作
  18. 图像数据增强 (Data Augmentation in Computer Vision)
  19. scala基本语法和单词统计
  20. dubbo源码解析-spi(4)

热门文章

  1. centos/redhat破解账号密码
  2. IDEA中tomcat的部署
  3. PAT Basic 1065 单身狗
  4. jquery源码 整体架构
  5. 经典平衡二叉树(AVL树)
  6. ERROR 000732:Output Geodatabase:Dataset Database Connections\Connection to localhost.sde\SDE.Dataset does not exist or is not supported
  7. Centos6.5安装Apache ab性能测试工具
  8. Python自用笔记
  9. 048 SparkSQL自定义UDAF函数
  10. 使用mini-textbox控件时 不能获取value值