Travel Plan

注意类似题目这种建树的方式,建出来可能是树,也可能是堆,而前者不一定是连续的编号,后者一定是连续的编号,这就导致了后者左右子树中一个是完全二叉树,另一个不是完全二叉树(这里就要利用这个性质优化时间复杂度);自己做的时候就是没有抓住这个性质导致没有做出来

显然考虑贡献,设si,j=x,我们挑出两个点作为路径的起点和终点,然后算这条路径的s=x的数量,但是发现算不出来,因为缺少长度,所以我们引入长度,假设这个路径的长度为y,那么方案数显然就是xy(x1)y;而除了这条路径的其余ny个点,染色方案数为mny;假设整棵树长度为y的路径有ky个,那么x对答案的贡献就是

y=1MAXLmny(xy(x1)y)kyx

(其中MAXL为最长路径,这个需要分类讨论),所以答案就为

x=1my=1MAXLmny(xy(x1)y)kyx

,考虑到kyx无关且MAXL很小,所以交换美剧顺序,有

y=1MAXLkyx=1mmny(xy(x1)y)x

所以现在的当务之急是计算kyunordered_map好像不能使用pair,所以我们用数组来DP(而不是用unordered_map

g[i][j]表示从根节点往下走了i层(每一层走的方向是确定的,我们都会向非完全二叉树的方向走;当然有时两个子树都是非完全二叉树,比如n=11,此时我们向右走),以当前节点为子树,长度为j的总方案数;h[i]表示从根节点往下走了i层,以当前节点为子树,这棵子树的深度(从0开始计数)

计算g[i][j]的时候,我们已经计算好了g[i+1],所以g[i][j]+=g[i+1][j]g[i][j]还要加上完全二叉树的这棵子树的贡献,这个比较容易计算,设G[i][j]表示深度为i的完全二叉树,长度为j的总路径数,推导见代码,于是g[i][j]+=G[h[i]1][j](假设右子树是非完全二叉树,左子树是非完全二叉树的情况有一点点小的改变,但是道理一样);接下来只需要计算经过经过当前根节点的路径就好了,这样的路径又分为两类,一类是根节点为端点,另一类是根节点为中转点。对于前者非常好计算,后者需要枚举一颗子树的长度(为了方便枚举非完全二叉树的长度)然后计算出另一颗子树的长度

时间复杂度为O(mlogn+Tlog3n)

posted @   最爱丁珰  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示