题解:用树链剖分来维护树链剖分

令d[x]=size[heavyson[x]]-size[lightson[x]]

当d[x]<0时轻重儿子关系改变

用数据结构维护d[x]并找到这些位置改变即可

时间复杂度O(不会分析)

#include<iostream>
#include<cstdio>
#include<cstring>
#define lo now<<1
#define ro now<<1|1
using namespace std;
const int maxn=200009; int n,m; long long nowans=0;
int havein[maxn],root=0;
int del[maxn]; int ls[maxn],rs[maxn];
int father[maxn],siz[maxn],dep[maxn];
int idp[maxn],top[maxn],ref[maxn],hson[maxn];
void Dfs1(int now,int fa){
father[now]=fa;
dep[now]=dep[fa]+1;
siz[now]=1;
if(ls[now]){
Dfs1(ls[now],now);
siz[now]+=siz[ls[now]];
if(siz[ls[now]]>siz[hson[now]])hson[now]=ls[now];
}
if(rs[now]){
Dfs1(rs[now],now);
siz[now]+=siz[rs[now]];
if(siz[rs[now]]>siz[hson[now]])hson[now]=rs[now];
}
} int dfsclock=0;
void Dfs2(int now,int toppoint){
if(now==toppoint)nowans-=now; idp[now]=++dfsclock;
ref[dfsclock]=now;
top[now]=toppoint;
if(!hson[now])return;
Dfs2(hson[now],toppoint);
if((ls[now])&&(ls[now]!=hson[now]))Dfs2(ls[now],ls[now]);
if((rs[now])&&(rs[now]!=hson[now]))Dfs2(rs[now],rs[now]);
} struct SegmentTree{
int l,r;
int tag,mn;//siz[heavy[now]]-siz[light[son]]
int havetop;//father[top[now]]
}tree[maxn<<2];
inline void pushup(int now){
tree[now].mn=min(tree[lo].mn,tree[ro].mn);
tree[now].havetop=(tree[lo].havetop|tree[ro].havetop);
}
inline void pushdown(int now){
if(tree[now].tag){
tree[lo].tag+=tree[now].tag;
tree[ro].tag+=tree[now].tag;
tree[lo].mn+=tree[now].tag;
tree[ro].mn+=tree[now].tag;
tree[now].tag=0;
}
} void BuildTree(int now,int l,int r){
tree[now].l=l;tree[now].r=r;
tree[now].tag=0;
if(l==r){
int x=ref[l];
tree[now].mn=siz[hson[x]]-min(siz[ls[x]],siz[rs[x]]);
tree[now].havetop=0;
return;
}
int mid=(l+r)>>1;
BuildTree(lo,l,mid);
BuildTree(ro,mid+1,r);
pushup(now);
} void Updatasec(int now,int ll,int rr,int x){
if(tree[now].l>=ll&&tree[now].r<=rr){
tree[now].tag+=x;
tree[now].mn+=x;
return;
}
int mid=(tree[now].l+tree[now].r)>>1;
pushdown(now);
if(ll<=mid)Updatasec(lo,ll,rr,x);
if(rr>mid)Updatasec(ro,ll,rr,x);
pushup(now);
} void Updatatop(int now,int ll,int rr,int x){
if(ll>rr)return;
if(tree[now].r<ll)return;
if(tree[now].l>rr)return;
if(tree[now].l==tree[now].r){
tree[now].mn+=x;
return;
}
pushdown(now);
if(tree[lo].havetop)Updatatop(lo,ll,rr,x);
if(tree[ro].havetop)Updatatop(ro,ll,rr,x);
pushup(now);
} void Changetop(int now,int ll,int rr){
if(ll>rr)return;
if(tree[now].r<ll)return;
if(tree[now].l>rr)return;
if(tree[now].l==tree[now].r){
tree[now].mn=-tree[now].mn;
tree[now].havetop=1;
int x=ref[tree[now].l];
if(ls[x]==hson[x]){
nowans=nowans-ls[x]+rs[x];
hson[x]=rs[x];
}else{
nowans=nowans-rs[x]+ls[x];
hson[x]=ls[x];
}
return;
}
pushdown(now);
if(tree[lo].mn<0)Changetop(lo,ll,rr);
if(tree[ro].mn<0)Changetop(ro,ll,rr);
pushup(now);
} void Updatapoint(int now,int p,int x){
if(tree[now].l==tree[now].r){
tree[now].mn+=x;
if(tree[now].mn<0){
tree[now].mn=-tree[now].mn;
tree[now].havetop=0;
int o=ref[p];
if(ls[o]==hson[o]){
nowans=nowans-ls[o]+rs[o];
hson[o]=rs[o];
}else{
nowans=nowans-rs[o]+ls[o];
hson[o]=ls[o];
}
}
return;
}
int mid=(tree[now].l+tree[now].r)>>1;
pushdown(now);
if(p<=mid)Updatapoint(lo,p,x);
else Updatapoint(ro,p,x);
pushup(now);
} void ChangePath(int u){
int x=u;
while(x){
int tx=top[x];
Updatasec(1,idp[tx],idp[x],-1); Updatatop(1,idp[tx],idp[x]-1,2);
Changetop(1,idp[tx],idp[x]-1);
// x=tx;int fa=father[x];
// if(!fa)break;
// if(hson[fa]!=x){
// Updatapoint(1,idp[fa],2);
// }else{
// Updatapoint(1,idp[fa],0);
// }
x=father[tx];tx=top[x];
}
x=u;
while(x){
x=top[x];
int fa=father[x];
if(!fa)break;
if(hson[fa]!=x){
Updatapoint(1,idp[fa],2);
}else{
Updatapoint(1,idp[fa],0);
}
x=fa;
}
} int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d%d",&ls[i],&rs[i]);
havein[ls[i]]++;
havein[rs[i]]++;
}
for(int i=1;i<=n;++i)nowans+=i;
for(int i=1;i<=n;++i)if(!havein[i])root=i; Dfs1(root,0);
Dfs2(root,root);
BuildTree(1,1,n); scanf("%d",&m);
printf("%lld\n",nowans);
del[0]=1;
while(m--){
int x;scanf("%d",&x); del[x]=1;
ChangePath(x);
if(ls[father[x]]==x){
if(del[rs[father[x]]])nowans-=x;
}else{
if(del[ls[father[x]]])nowans-=x;
}
printf("%lld\n",nowans);
}
return 0;
}

  

BZOJ 4855 [Jsoi2016]轻重路径的更多相关文章

  1. BZOJ4855 : [Jsoi2016]轻重路径

    首先用树状数组维护dfs序来快速支持一个点子树大小的询问. 每次删掉一个叶子时,从根开始往叶子走,显然只有$2size[x]\leq size[father]$的点的父亲才有可能换重儿子. 从根开始往 ...

  2. [JSOI2016]轻重路径[树链剖分]

    题意 题目链接 分析 先对原树树剖,在一次删点操作后从根节点开始二分,如果一条边从重边变成轻边,必然有 \(size_u\le \frac{1}{2}size_{rt}\) (取等号是特判对应儿子消失 ...

  3. BZOJ 4753 [Jsoi2016]最佳团体 | 树上背包 分数规划

    BZOJ 4753 [Jsoi2016]最佳团体 | 树上背包 分数规划 又是一道卡精度卡得我头皮发麻的题-- 题面(--蜜汁改编版) YL大哥是24OI的大哥,有一天,他想要从\(N\)个候选人中选 ...

  4. BZOJ 2337 XOR和路径 | 高斯消元 期望 位运算

    BZOJ 2337 XOR和路径 题解 这道题和游走那道题很像,但又不是完全相同. 因为异或,所以我们考虑拆位,分别考虑每一位: 设x[u]是从点u出发.到达点n时这一位异或和是1的概率. 对于所有这 ...

  5. 【LOJ】#2079. 「JSOI2016」轻重路径

    题解 写数据结构的时候我代码就会变得非常非常长 一看别人1.5K 2.3K 我6.3K-- orzzzzz 我们很容易想到离线倒着插入,然而,有个小锅叫如果size相同保持原来的重儿子不变 我们需要写 ...

  6. [BZOJ 1907] 树的路径覆盖 【树形DP】

    题目链接:BZOJ - 1907 题目分析 使用树形 DP,f[x][0] 表示以 x 为根的子树不能与 x 的父亲连接的最小路径数(即 x 是一个折线的拐点). f[x][1] 表示以 x 为根的子 ...

  7. BZOJ.3784.树上的路径(点分治 贪心 堆)

    BZOJ \(Description\) 给定一棵\(n\)个点的带权树,求树上\(\frac{n\times(n-1)}{2}\)条路径中,长度最大的\(m\)条路径的长度. \(n\leq5000 ...

  8. bzoj 3784: 树上的路径【点分治+st表+堆】

    参考:https://www.cnblogs.com/CQzhangyu/p/7071477.html 神奇的点分治序(或者叫点剖?).就是把点分治扫过的点依次放进队列里,然后发现,对于每一棵树摊到序 ...

  9. BZOJ 3784: 树上的路径

    Description 问一棵树上前 \(k\) 大路径的边权. Sol 边分治. 非常感谢数据没有菊花图. 为了写写边分治试试然后就开了这道题. 边分治非常好想,选一条重边,分成两部分,然后分别求最 ...

随机推荐

  1. Metasploit学习笔记——Web应用渗透技术

    1.命令注入实例分析 对定V公司网站博客系统扫描可以发现,它们安装了zingiri-web-shop这个含有命令注入漏洞的插件,到www.exploit-db.com搜索,可以看到2011.11.13 ...

  2. EventLoop

    文章资料来自 Node.js 事件循环机制 JS灵魂之问(下) EventLoop的中国名字叫事件循环,这个玩意真的是高深莫测,一般开发都用不到,代码只管写就行,虽然不用懂,但是面试就是要问,这对我这 ...

  3. Redis详解(五)——主从复制

    Redis详解(五)--主从复制 面临问题 机器故障.我们部署到一台 Redis 服务器,当发生机器故障时,需要迁移到另外一台服务器并且要保证数据是同步的.而数据是最重要的,如果你不在乎,基本上也就不 ...

  4. Ubuntu 14.04 配置 VNC Server

    用putty连接Linux后,如果会话断开,也会终止此会话在Linux执行的任务. 用WinSCP传输文件很方便,目前也只能传输文件. 按照以下步骤以及提示,安装VNC Server, 1.apt-g ...

  5. 【LeetCode】101. 对称二叉树

    题目 给定一个二叉树,检查它是否是镜像对称的. 例如,二叉树 [1,2,2,3,4,4,3] 是对称的. 1 / \ 2 2 / \ / \ 3 4 4 3 但是下面这个 [1,2,2,null,3, ...

  6. cf 785#

    23333再次水惨了..(心酸啊) A题呵呵呵呵呵 #include<cstdio> #include<iostream> using namespace std; int m ...

  7. T_SQL 将一列多行数据合并为一行

    SQL Server在进行数据迁移和报表处理的时候会遇到将一列多行数据拼接为一个字符串的情况,为了处理这个问题,在网上找了一些相关的资料,提供两种方法,供遇到类似问题的朋友们参考,也借此加深自己的印象 ...

  8. VUE随手记坑

    1.el-select 默认选中的问题 <el-select v-model="temp.audit" placeholder="请选择"> < ...

  9. java04异常处理课堂总结

    一,动手动脑 1,请阅读并运行AboutException.java示例,然后通过后面的几页PPT了解Java中实现异常处理的基础知识. import javax.swing.*; class Abo ...

  10. HDU 5461:Largest Point

    Largest Point Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) To ...