19CSP-S十一集训三地联考—众神归位

T2 树链剖分

(http://zhengruioi.com/problem/1120)
gu~gu~gu~

sol:

这题就是一个很经典的树形DP换根。考虑因为是树链剖分,所以不同深度的节点是互不影响的。那DP就只要考虑当前节点连出的边中,被覆盖次数最多的即可。
主要是复习一下换根法。首先做出以\(1\)为根的情况,处理出边被覆盖次数最多和次多的情\(son1[x]\)和\(son2[x]\)。考虑选择的根深度逐渐变大,每次只要修改一下答案,然后更新\(son1[x]\)和\(son2[x]\)即可。
记住在退出前一定要回到进来前的状态。

code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
    int x=0;char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x;
}
const int N=100005;
int n,m,st[N][20],dep[N],val[N],son1[N],son2[N],ans,tmp;
int ver[N<<1],nxt[N<<1],head[N],tot,len,num;
inline void add(int x,int y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
void dfs1(int x,int la){
    st[x][0]=la;dep[x]=dep[la]+1;
    for(int i=1;(1<<i)<dep[x];i++)
        st[x][i]=st[st[x][i-1]][i-1];
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        if(y==la) continue;
        dfs1(y,x);
    }
}
inline int getlca(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    for(int i=19;i>=0;i--){
        if((1<<i)>dep[x]-dep[y]) continue;
        x=st[x][i];len+=(1<<i);
    }
    if(x==y) return x;
    for(int i=19;i>=0;i--){
        if(st[x][i]==st[y][i]) continue;
        x=st[x][i];y=st[y][i];
        len+=(1<<i+1);
    }
    len+=2;return st[x][0];
}
void dfs2(int x,int la){
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        if(y==la) continue;
        dfs2(y,x);
        val[x]+=val[y];
    }
    if(son1[la]<val[x]) son2[la]=son1[la],son1[la]=val[x];
    else if(son2[la]<val[x]) son2[la]=val[x];
    num+=son1[x];
}
void dfs3(int x,int la){
    for(int i=head[x];i;i=nxt[i]){
        int y=ver[i];
        if(y==la) continue;
        int tmp1=son1[y],tmp2=son2[y],tmp3=son1[x],tmp4=son2[x];
            //这里一定要把这些信息备份一下,供以后退回原来状态时使用
        if(val[y]==tmp3) num=num-tmp3+tmp4;
        if(val[y]>tmp1) num=num-tmp1+val[y],son2[y]=son1[y],son1[y]=val[y];
        else if(val[y]>tmp2) son2[y]=val[y];
        ans=max(ans,num);
        dfs3(y,x);
        if(val[y]==tmp3) num=num+tmp3-tmp4;
        if(val[y]>tmp1) num=num+tmp1-val[y],son2[y]=tmp2,son1[y]=tmp1;
        else if(val[y]>tmp2) son2[y]=tmp2;
    }

}
int main(){
    n=read();m=read();
    for(int i=1;i<n;i++){
        int x=read(),y=read();
        add(x,y);add(y,x);
    }
    dfs1(1,0);
    for(int i=1;i<=m;i++){
        int x=read(),y=read();
        int lca=getlca(x,y);
        val[x]++;val[y]++;
        val[lca]-=2;
    }
    dfs2(1,0);ans=num;
    dfs3(1,0);
    printf("%d\n",len-ans);
    return 0;
}

原文地址:https://www.cnblogs.com/zxynothing/p/11700783.html

时间: 2024-08-30 18:22:49

19CSP-S十一集训三地联考—众神归位的相关文章

19CSP-S十一集训三地联考—众神归位 题解总结

订正了三天的题目 自闭.... T1 幸福T2 树链剖分 考虑到 对于一个 树 确定覆盖哪几条边 不会随着 树的根节点的改变而改变 而且 这种对于一个无根树的路径进行覆盖 我们显然可以想到 树上差分 对于边的差分 对于一条路径从s到t 我们类比序列上的差分 即 $sum[s]--,sum[t]--,sum[lca(s,t)]-=2$ 所以进行一遍dfs 求出一个节点的子树权值和 就是从这个点的父节点 到这个点 被覆盖了多少次 所以我们 求出所有的和就是整棵树所有边被覆盖的次数 记作res 然后单

「CSPS 2019 十一」三地联考

因为版权原因,不放题面. 幸福 Solution 只会写 \(70\) 分的找规律代码,可以考虑每个斐波那契数对卷积的贡献,发现贡献是类似于倒斐波那契数列,就可以 \(O(n)\) 做了,有 \(70\) 分. std 是化简一下式子,化简结果为 \[F_n = F_{n-1} + F_{n-2} + f_n\] 发现这是一个递推式,用矩阵乘法加速即可.但是我不会矩阵乘法,先咕了.不会矩阵乘法也可以用退出来的递推式拿 \(70\) 分. Code #include <bits/stdc++.h>

ZROI1119 【十一&#183;联考】幸福

ZROI1119 [十一·联考]幸福 传送门 一道矩阵快速幂. #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define ll long long #include<cmath> const int mod=998244353; using namespace std; struct matrix { ll data[7][7]; void

8.9联考题解

今天的题有质量多了,尤其是第一题不再毫无意义,果然考这样的试比较有收获. 时间限制:1sec  内存限制:128MB 题解       刚开始看的时候没有思路.不过这样的考试才叫正常嘛,前两天T1那是什么玩意= =.边读题边写前缀和.离散之类的词,但是前缀和并不能处理出题目中所要求的情况,3*10^5大概最多nlogn.举了几个例子,发现好像和后面大于它的数有关,想了想怎么求它后面大于它的数字个数,过了一会猛然发现我举的例子也太特殊了,全都是单调递增的,有点挫败,就去做后面的题了.T2做了很久还

jloi2017(shoi2017?)六省联考酱油记

Day -n 听说了4.22.4.23的省选,而且还是六省联考. 压力山大. 尽管我只是一名高一的simple OIer,在省选到来之前,心里还是很紧张的. 毕竟自己也知道南方dalao们都是神犇,像我这种巨蒻能考成什么样还很不好说. 感觉当时的紧张气氛堪比中考前. Teacher:这次省选就是让你们体验一下考试氛围的,并没有指望你们有多好的成绩,自己写好暴力就行了,不必非要写正解. 嗯,我本来就是去打酱油的,不在乎成绩. 考试前几天敲敲模板,博客也不写了,全力准备考试. Day 0 考前的晚上

3.5~3.6联考题解

本来想加个密码的,后来一想全HE就咱们这几个人,外省的dalao愿看也没事儿,就公开算了,省得加密码各种麻烦. 先补这两天的题解吧--如果有空的话我可能会把上次联考的题解补上= =(中午没睡觉,现在困得很,根本没法写题-- 算算算number 感觉出题人出题的时候zz了吧,费了半天搞出来一个极其麻烦还跑得慢的做法是要闹哪样啊-- 算了,写一写$O(nk)$做法的推导过程吧,虽然其实非常好推-- 首先定义$S_i$表示到$1~i$位置的前缀和,并且规定$S_0=0$,那么 \begin{align

10.29 FJ四校联考

//四校联考Rank 16 感觉很滋磁 (虽然考的时候抱怨厦门一中出的数学题很NOIP///) 圈地 [问题描述] n根长度不一定相同的木棍,至多可以对其中一根切一刀,然后用其中的任意根围一个三角形,求三角形的最大面积.设面积为S,输出16*S^2对998244353取模后的答案.特别地,无解输出-1. 注:退化的三角形(面积为零)不被认为是三角形,答案应该为-1. [输入文件] 输入文件为tri.in. 输入文件第一行包含两个正整数n和998244353. 第二行包含n个正整数,表示每根木棍的

因第三次月考而引起的

这么久没有考试了,一连翘掉了期末.入学.第一次月考.期中考试.本来这一次的第三次月考是要求全组参加的,但是,俗话说:“计划赶不上变化”.确实如此,在明天就要第三次月考的晚自习前,我们还在搞大扫除,忽然,远远望见教练的身影,他过来说:“联赛400分以上的不要参加月考,从明天开始准备冬令营.”我们这些人(4个)真是一脸茫然的样子.马上又去找了教练,他说年级组要求我们参加月考因我们不能参加冬令营.不过教练还是说会去和年级组谈一谈. 不知怎么办的我们遭遇了这当头的一棒,马上,准备去找年级组长,我们的理由

bzoj千题计划265:bzoj4873: [六省联考2017]寿司餐厅

http://www.lydsy.com/JudgeOnline/problem.php?id=4873 选a必选b,a依赖于b 最大权闭合子图模型 构图: 1.源点 向 正美味度区间 连 流量为 美味度 的边 2.负美味度区间 向 汇点 连 流量为 美味度的绝对值 的边 3.区间[i,j] 向 区间[i+1,j].区间[i,j-1] 连 流量为 inf 的边 4.区间[i,i] 向 寿司i 连 流量为 inf 的边 5.寿司i 向 汇点 连 流量为 寿司代号 的边 6.寿司i 向 它的代号 连