P3565 [POI2014]HOT-Hotels(树形dp+长链剖分)

P3565 [POI2014]HOT-Hotels

参考题解

题目大意:
给定一棵树,在树上选 3 个点,要求两两距离相等,求方案数。

三个点树上两两距离为d存在下面两种情况

  • 某个点三个子树(保证该点是LCA)中分别由三个点距离它为d
  • 对于某一个点,它的 d 级祖先以及子树内两个以它为LCA,距它 d 的点

对于情况一,设计dp: fu,jf_{u,j}fu,j表示以uuu为根的子树,距i距离为jjj的点数

对于情况二,设计dp:gu,jg_{u,j}gu,j表示以uuu为根的子树,两个点的到LCA距离相等(此出用d表示),LCA到uuu的距离为d−jd-jdj点对

对于fu,jf_{u,j}fu,j的状态转移十分显然:fu,j=∑v∈sonufv,j−1f_{u,j}=\sum_{v\in son_u }f_{v,j-1}fu,j=vsonufv,j1

而对于gu,jg_{u,j}gu,j来说存在两种情况

  • 某个子树内部存在两个点:gu,j=∑v∈sonugv,j+1g_{u,j}=\sum_{v\in son_u}g_{v,j+1}gu,j=vsonugv,j+1
  • 两个不同的子树各贡献一个点,以uuu为LCA:gu,j=∑v,w∈sonu,v≠wfv,j−1×fw,j−1g_{u,j}=\sum_{v,w\in son_u,v \ne w} f_{v,j-1}×f_{w,j-1}gu,j=v,wsonu,v=wfv,j1×fw,j1

很明显,第二中情况fv,j−1×fw,j−1,fw,j−1×fv,j−1f_{v,j-1}×f_{w,j-1}, f_{w,j-1}×f_{v,j-1}fv,j1×fw,j1,fw,j1×fv,j1是同一种情况,这里我们让vvvuuu较靠前的儿子即可避免重复计算

而对于答案计算来说也存在两种情况:
首先对于三个点树上两两距离为d的情况都可以看成两个点在一个子树中,而另一个点“别处

  • 在子树vvv中选一个点,而在其他子树中选两个点:gu,j+1×fv,jg_{u,j+1}×f_{v,j}gu,j+1×fv,j
  • 在子树vvv中选两个点,而在其他子树中选一个点:fu,j−1×gv,jf_{u,j-1}×g_{v,j}fu,j1×gv,j

同样为了避免重复计算只需要让其他子树搞成vvv前面的子树即可
注意上述gu,j+1g_{u,j+1}gu,j+1fu,j−1f_{u,j-1}fu,j1都还未算vvv对其的贡献,这个只需要先计算答案在加贡献即可。

计算状态数组和答案时,都有计算前面子树的情况,直接运用前缀和的思想即可边计算答案,边转移数组。

这里要提一点,我们至今没有提到gu,0g_{u,0}gu,0对答案的贡献,它确实对答案有贡献,但是我们已经计算过了,如果在此加上会重复计算。

而其他博主在计算的时候加上gu,0g_{u,0}gu,0实际上增加的时gwson,1g_{wson,1}gwson,1即重儿子的贡献。

根据g的转移方程可知道:gu,0g_{u,0}gu,0的贡献全部来自于∑v∈sonugv,1\sum_{v\in son_u}g_{v,1}vsonugv,1,而计算fu,j−1×gv,jf_{u,j-1}×g_{v,j}fu,j1×gv,j对答案的贡献时我们具体写一下fu,0×gv,1f_{u,0}×g_{v,1}fu,0×gv,1fu,0=1f_{u,0}=1fu,0=1,因此已经计算过gu,0g_{u,0}gu,0的贡献!!!


然后就是长链剖分优化dp,每次保存长儿子的贡献,其他儿子暴力合并,每条长链都会在链头暴力合并一次时间复杂度O(len)O(len)O(len)总的合并时间复杂度O(n)O(n)O(n)

最后如果写指针版本的话,由于g数组是倒着转移的,fff要多开一倍的内存,否则g可能倒回来覆盖掉fff

code

#define IO ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
using ll=long long;
constexpr int N=5010;
int h[N],e[2*N],ne[2*N],idx;
void add(int a,int b){e[idx]=b,ne[idx]=h[a],h[a]=idx++;}
int n;
int dep[N],son[N];
void dfs1(int u,int fa)
{for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==fa) continue;dfs1(v,u);if(dep[v]>dep[son[u]]) son[u]=v;}dep[u]=dep[son[u]]+1;
}ll pool[4*N];
ll *f[N],*g[N],*now=pool;
ll ans;
void dfs2(int u,int fa)
{f[u][0]=1;if(son[u]){f[son[u]]=f[u]+1;g[son[u]]=g[u]-1;dfs2(son[u],u);ans+=g[son[u]][1];// 加上重儿子的贡献}for(int i=h[u];i!=-1;i=ne[i]){int v=e[i];if(v==fa||v==son[u]) continue;f[v]=now;now+=dep[v]<<1;g[v]=now;now+=dep[v];dfs2(v,u);// 边计算for(int j=0;j<dep[v];j++){if(j) ans+=f[u][j-1]*g[v][j];ans+=g[u][j+1]*f[v][j];}// 边转移for(int j=0;j<dep[v];j++){g[u][j+1]+=f[u][j+1]*f[v][j];if(j) g[u][j-1]+=g[v][j];f[u][j+1]+=f[v][j];}}}
int main()
{IO;cin>>n;memset(h,-1,sizeof h);for(int i=1;i<n;i++){int u,v;cin>>u>>v;add(u,v);add(v,u);}dfs1(1,0);f[1]=now;now+=dep[1]<<1;//多开一倍的内存g[1]=now;now+=dep[1];dfs2(1,0);cout<<ans<<'\n';return 0;
}

菜菜的我搞了一天这个题啊啊啊啊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319041.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#的RSA加密解密签名,就为了支持PEM PKCS#8格式密钥对的导入导出

差点造了一整个轮子.Net Framework 4.5 里面的RSA功能&#xff0c;并未提供简单对PEM密钥格式的支持&#xff08;.Net Core有咩&#xff1f;&#xff09;&#xff0c;差点&#xff08;还远着&#xff09;造了一整个轮子&#xff0c;就为了支持PEM PKCS#8、PKCS#1格式密钥对的导…

P4494-[HAOI2018]反色游戏【圆方树】

正题 题目链接:https://www.luogu.com.cn/problem/P4494 题目大意 给出nnn个点mmm条边的一张无向图&#xff0c;节点有0/10/10/1&#xff0c;每条边可以选择是否取反两边的点。 开始求将所有节点变为000的方案&#xff0c;然后对于每个点询问删去这个点之后的方案 1≤T≤5,1…

福州首届.NET开源社区技术交流会圆满成功

活动总结2018年11月10日周六的下午&#xff0c;在福州蒲公英创新工场举办了福州首届.NET开源社区技术交流会&#xff0c;来自福建省各大科技公司的技术小伙伴齐聚一堂&#xff0c;为了就是能在现场学习到微软跨平台技术.NET Core、微服务以及Azure云服务。在交流会现场&#xf…

【模板】高精度

ACM模板 #include<string> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct bign {int d[200010], len;bign() { memset(d, 0, sizeof d); len 1; }bign(int num) { *this num; }big…

POJ3734-Blocks【EGF】

正题 题目链接:http://poj.org/problem?id3734 题目大意 用思种颜色给nnn个格子染色&#xff0c;要求前两种颜色出现偶数次&#xff0c;求方案。 1≤T≤100,1≤n≤1091\leq T\leq 100,1\leq n\leq 10^91≤T≤100,1≤n≤109 解题思路 反正是EGF\text{EGF}EGF的十分入门题了。…

[蓝桥杯][2017年第八届真题]对局匹配

题目描述 小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分&#xff0c;代表他的围棋水平。 小明发现网站的自动对局系统在匹配对手时&#xff0c;只会将积分差恰好是K的两名用户匹配在一起。如果两人分差小于或大于K&#xff0c;系统都不会将他们…

codeforce23 E. Tree(高精度+树形dp)

E. Tree 状态表示&#xff1a;fu,jf_{u,j}fu,j​表示以uuu节点的子树&#xff0c;uuu所在连通块大小为jjj时&#xff0c;并且没有算上uuu连通块的贡献的最大值 状态计算&#xff1a; 对于一棵子树vvv来说&#xff0c;显然可以有两种情况 uuu节点与vvv节点不连通&#xff1a;fu…

.NET Core开发者的福音之玩转Redis的又一傻瓜式神器推荐

引子为什么写这篇文章呢&#xff1f;因为.NET Core的生态越来越好了&#xff01;之前玩转.net的时候操作Redis相信大伙都使用过一些组件&#xff0c;但都有一些缺点&#xff0c;如ServiceStack.Redis 是商业版&#xff0c;免费版有限制&#xff1b;StackExchange.Redis 是免费版…

CF891E-Lust【EGF】

正题 题目链接:https://www.luogu.com.cn/problem/CF891E 题目大意 nnn个数字的一个序列aia_iai​&#xff0c;每次随机选择一个让它减去一。然后贡献加上所有其他aia_iai​的乘积。 执行kkk次&#xff0c;求贡献答案。 1≤n≤5000,0≤ai,k≤1091\leq n\leq 5000,0\leq a_i,k…

P2495 [SDOI2011]消耗战(树形dp+虚树)

P2495 [SDOI2011]消耗战 树形dp 状态表示&#xff1a;fuf_ufu​表示以uuu为根的子树中&#xff0c;uuu节点与子树中的关键的“隔开”所需要的最小代价 状态转移&#xff1a; 考虑uuu的一个儿子vvv vvv是关键点&#xff1a;fufuwu→vf_uf_uw_{u\to v}fu​fu​wu→v​vvv不是关键…

牛客题霸 车站建造问题 C++题解/答案

题目描述 有108个村庄排在一条公路上&#xff0c;依次编号为0~108-1&#xff0c;相邻村庄距离为1&#xff0c;其中有n个村庄居住着牛牛&#xff0c;居住着牛牛的村庄从小到大依次为a0~an-1&#xff0c;其中保证a00. 现在需要建设车站&#xff0c;有两个要求必须被满足&#xf…

【.NET Core项目实战-统一认证平台】第四章 网关篇-数据库存储配置(2)

上篇文章我们介绍了如何扩展Ocelot网关&#xff0c;并实现数据库存储&#xff0c;然后测试了网关的路由功能&#xff0c;一切都是那么顺利&#xff0c;但是有一个问题未解决&#xff0c;就是如果网关配置信息发生变更时如何生效&#xff1f;以及我使用其他数据库存储如何快速实…

P5666-[CSP-S2019]树的重心【树状数组】

正题 题目链接:https://www.luogu.com.cn/problem/P5666 题目大意 给出nnn个点的一棵树&#xff0c;对于每条边割掉后两棵树重心编号和。 1≤T≤5,1≤n≤2999951\leq T\leq 5,1\leq n\leq 2999951≤T≤5,1≤n≤299995 解题思路 编号和&#xff0c;所以应该是要我们枚举点然后…

牛客题霸 牛妹的蛋糕 C++题解/答案

题目描述 众所周知&#xff0c;牛妹非常喜欢吃蛋糕。 第一天牛妹吃掉蛋糕总数三分之一&#xff08;向下取整&#xff09;多一个&#xff0c;第二天又将剩下的蛋糕吃掉三分之一&#xff08;向下取整&#xff09;多一个&#xff0c;以后每天吃掉前一天剩下的三分之一&#xff08…

计算机提示找不到vcruntime140.dll,无法继续执行代码怎么办?如何修复

“找不到vcruntime140.dll&#xff0c;无法继续执行代码”。这个问题可能会让你感到困惑&#xff0c;不知道如何解决。那么&#xff0c;vcruntime140.dll是什么文件&#xff1f;它为什么会丢失&#xff1f;又该如何解决这个问题呢&#xff1f;本文将为你详细介绍vcruntime140.d…

codeforces1486 F. Pairs of Paths(倍增+树上数数)

F. Pairs of Paths syksykCCC题解 iamhpp题解 首先说明&#xff0c;下面图片来自第一篇博客&#xff0c;下面代码照抄第二篇博客 对没有啥是自己写的&#xff08;因为我太菜~~ 从上图可以看出两条链只有一个交点可能有两种情况 交点是两条链的LCA交点是一条链的LCA而不是另一…

学习Raft算法的笔记

Raft是一种为了管理日志复制的一致性算法。它提供了和Paxos算法相同的功能和性能&#xff0c;但是它的算法结构和Paxos不同&#xff0c;使得Raft算法更加容易理解并且更容易构建实际的系统。为了提升可理解性&#xff0c;Raft将一致性算法分解成几个关键的模块&#xff0c;例如…

P3335-[ZJOI2013]蚂蚁寻路【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P3335 题目大意 给出nmn\times mnm的网格&#xff0c;每个格子有权值。一个回路在格子的边上&#xff0c;要求有2k2\times k2k次左转&#xff0c;其他都是右转&#xff0c;且最后222次一定得是右转。 求包含的格子权值和最大…

牛客题霸 最少素数拆分 C++题解/答案

牛客题霸 最少素数拆分 C题解/答案 题目描述 牛牛刚刚学习了素数的定义&#xff0c;现在给定一个正整数N&#xff0c;牛牛希望知道N最少表示成多少个素数的和。 素数是指在大于1的自然数中&#xff0c;除了1和它本身以外不再有其他因数的自然数。 提示 哥德巴赫猜想&#xf…

LOJ dfs序1234

DFS 序 1 题目要求&#xff1a; ① uuu节点权值xxx ② 询问uuu子树权值和 uuu节点权值xxx &#xff1a;直接加uuu子树权值和&#xff1a;dfs序树状数组 LOJ提交代码 DFS 序 1 DFS 序 2 题目要求&#xff1a; ① uuu节点子树权值xxx ② 询问uuu子树权值和 uuu节点子树权值xxx&…