1 条题解
-
0
自动搬运
来自洛谷,原作者为

by_chance
还好我拥有不同的宇宙,能治愈所有我偏执的梦。搬运于
2025-08-24 22:46:13,当前版本为作者最后更新于2023-05-23 21:58:21,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
由于每次删点之后新增的边数太多,所以考虑拆边。用一个白点表示一条边,并将原来树中的点称为黑点,编号不变。对于第 条边 ,在 间连边,得到一棵树 。
删除点 时,我们将点 相邻的所有白点合并为一个点,然后删除 。容易归纳证明:每次删除后 仍然是树;真实的 间有边等价于树 中存在一个白点与 均相邻。
因为依次删除 ,所以在树 中,可以把点 作为根。这样每次删除时,就可以把 的所有相邻白点合并到 的父亲白点上去。然后,用并查集维护每个白点被合并到了哪个点。
用 表示在初始的 中 的父亲结点, 表示某个时刻白点 被合并到的点。那么,在这一时刻,黑点 的父亲结点是 ,白点 的父亲节点是 。
下面来考虑如何统计答案。对白点 ,记 为 的儿子个数。
对于一个符合要求的 ,设 通过白点 相连, 通过白点 相连。
- 如果 :固定 ,在 的邻点中任选 个,则对答案的贡献为 求和的条件是 是白点。
- 如果 ,且 都是 的子节点:固定 ,先任取 的两个子结点 ,此时贡献 。则总的贡献为 第一个求和的条件是 是黑点,后两个求和的条件是 是 的儿子。 注意到后一项拆出来就是对所有白点 求 的和,那就拆出来吧。
- 如果 ,且 一个是 的子结点,另一个是 的父亲结点:不妨 是 的父亲结点,固定 , 是 的一个子结点, 又是 的一个子结点,则对答案的贡献为 三个求和的条件分别为 是白点, 是 的子结点, 是 的结点。
列出式子后,我们发现需要维护以下数据:
- 白点 的儿子数目
- 黑点 的儿子的 值之和,也可以存到数组 里
- 白点 的儿子的 值之和
答案是 ,其中 ,两个求和的条件分别是 是黑点, 是白点。
删除点 时,枚举它初始的的儿子(一定没有被合并过),在并查集中将其合并到 的父亲中。然后清零 和 的儿子的值,更新 的三层祖先的值,并更新答案。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=4e5+5; int n,fa[N],p[N];ll s[N],t[N],ans; int head[N],ver[N<<1],nxt[N<<1],tot; void add(int u,int v){ver[++tot]=v;nxt[tot]=head[u];head[u]=tot;} void dfs(int u){ for(int i=head[u],v;i;i=nxt[i]) if((v=ver[i])!=fa[u]){ fa[v]=u;dfs(v); if(u<=n)s[u]+=s[v]; else ++s[u],t[u]+=s[v]; } } int find(int x){return (x==p[x]?x:(p[x]=find(p[x])));} ll f(ll x){return x*x*x-x*x-x;} int main(){ scanf("%d",&n); for(int i=1,u,v;i<n;i++){ scanf("%d%d",&u,&v); add(u,n+i);add(v,n+i);add(n+i,u);add(n+i,v); } dfs(n); for(int i=1;i<2*n;i++)p[i]=i; for(int i=1;i<=n;i++)ans+=s[i]*s[i]; for(int i=n+1;i<2*n;i++)ans+=f(s[i])+2*s[i]*t[i]; for(int u=1;u<=n;u++){ printf("%lld\n",ans); int g=find(fa[u]),w=fa[g];ll del=-1; ans-=f(s[g])+2*s[g]*t[g]+s[w]*s[w];s[w]-=s[g];--s[g]; t[g]-=s[u];ans-=s[u]*s[u];s[u]=0; for(int i=head[u],v;i;i=nxt[i]) if((v=ver[i])!=fa[u]){ p[v]=g;s[g]+=s[v];t[g]+=t[v];del+=s[v]; ans-=f(s[v])+2*s[v]*t[v];s[v]=t[v]=0; } s[w]+=s[g];ans+=f(s[g])+2*s[g]*t[g]+s[w]*s[w]; t[w=find(fa[fa[g]])]+=del;ans+=2*s[w]*del; } return 0; }Upd:修改了格式。
- 1
信息
- ID
- 8566
- 时间
- 2000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者