Description

Solution

神仙操作orz。

首先看数据范围,显然不可能是O(n2)的。(即绝对不是枚举那么简单的),我们考虑dp。

定义f(x,k)为以x为根的子树中与x距离为k的节点数;g(x,k)为在以x为根的子树中选择两个点,使得另一个点应在x子树外且离x距离为k的方案数(或者距离为0)。但是这样子暴力转移怕是会崩em,考虑优化。

这里的树是棵静态树,考虑树链剖分,点分治之类的思想。

最后,由于很多时候它的复杂度和树的高度有关,考虑长链剖分。

转移的话,暴力枚举所有轻链(啊我可能说的不是很清楚,类似启发式合并的想法吧)。

那么该点对应的长链怎么办呢?类似树剖的重儿子,我们定义节点x的长儿子为son[x],它是只有一个的。

而假如该点只有一个儿子,f(x,k)=f(son[x],k-1),g(x,k)=g(son[x],k+1)。

还是和树剖一样的思想,我们把同一条长链的信息存在一起,例如把f(son[x],k-1)的信息与f(x,k)存在同一个地址下。(我们能这么做是因为son[x]的信息在被x更新完后它就没用了啊)。g的话同理。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=;
int mxdep[N],top[N],fa[N],dep[N],son[N],cnt_f[N],cnt_g[N],cntf=,cntg=;
ll F[N],G[N<<];
int getlen(int x){return mxdep[x]-dep[x]+;}
ll &f(int x,int y){return F[cnt_f[top[x]]+dep[x]-dep[top[x]]+y];}
ll &g(int x,int y){return G[cnt_g[top[x]]-dep[x]+dep[top[x]]+y];}
struct _pas{int y,nxt;}_g[N<<];int h[N],tot=;
void dfs1(int x,int f)
{
fa[x]=f;dep[x]=dep[f]+;mxdep[x]=dep[x];son[x]=;
for (int i=h[x];i;i=_g[i].nxt)
if (_g[i].y!=f){
dfs1(_g[i].y,x);
mxdep[x]=max(mxdep[x],mxdep[_g[i].y]);
if (mxdep[son[x]]<mxdep[_g[i].y]) son[x]=_g[i].y;
}
}
void dfs2(int x)
{
top[x]=son[fa[x]]==x?top[fa[x]]:x;
if (top[x]==x)
{
int d=getlen(x);
cnt_f[x]=cntf;cnt_g[x]=cntg+d;
cntf+=d;cntg+=*d;
}
if (son[x]) dfs2(son[x]);
for (int i=h[x];i;i=_g[i].nxt)
if (_g[i].y!=son[x]&&_g[i].y!=fa[x]) dfs2(_g[i].y);
}
ll ans;
void dp(int u)
{
f(u,)=;
if (son[u]) dp(son[u]),ans+=g(u,);
for (int i=h[u];i;i=_g[i].nxt)
if (_g[i].y!=son[u]&&_g[i].y!=fa[u])
{
int v=_g[i].y;dp(v);int len=getlen(v);
for (int i=;i<=len;i++) ans+=g(u,i)*f(v,i-);
for (int i=;i<len;i++) ans+=g(v,i)*f(u,i-);
for (int i=;i<=len;i++) g(u,i)+=f(u,i)*f(v,i-);
for (int i=;i<=len-;i++) g(u,i)+=g(v,i+);
for (int i=;i<=len;i++) f(u,i)+=f(v,i-);
}
}
void _clear()
{
tot=cntf=cntg=;
memset(h,,sizeof(h));
memset(F,,sizeof(F));
memset(G,,sizeof(G));
}
int n,x,y;
int main()
{
while ()
{
scanf("%d",&n);
if (!n) return ;
_clear();
for (int i=;i<n;i++)
{
scanf("%d%d",&x,&y);
_g[++tot]=_pas{y,h[x]};h[x]=tot;
_g[++tot]=_pas{x,h[y]};h[y]=tot;
}
ans=;
dfs1(,);dfs2();dp();
printf("%lld\n",ans);
}
}

[2016北京集训试题7]thr-[树形dp+树链剖分+启发式合并]的更多相关文章

  1. 【BZOJ3522】【BZOJ4543】【POI2014】Hotel 树形DP 长链剖分 启发式合并

    题目大意 ​ 给你一棵树,求有多少个组点满足\(x\neq y,x\neq z,y\neq z,dist_{x,y}=dist_{x,z}=dist_{y,z}\) ​ \(1\leq n\leq 1 ...

  2. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  3. 6.3 省选模拟赛 Decompose 动态dp 树链剖分 set

    LINK:Decompose 看起来很难 实际上也很难 考验选手的dp 树链剖分 矩阵乘法的能力. 容易列出dp方程 暴力dp 期望得分28. 对于链的情况 容易发现dp方程可以转矩阵乘法 然后利用线 ...

  4. BZOJ4712洪水——动态DP+树链剖分+线段树

    题目描述 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到 山顶放了格水.于是小A面前出现了一个瀑布.作为平民的小A只好老实巴交地爬山堵水.那么 ...

  5. acm 2015北京网络赛 F Couple Trees 树链剖分+主席树

    Couple Trees Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/123 ...

  6. [2016北京集训试题8]连在一起的幻想乡[dp+无向图计数]

    Description Solution 本博客参考yww大佬的博客,为了加深理解我就自己再写一遍啦. 以下的“无向图”均无重边无自环. 定义f0[n]为n个点构成的无向图个数,f1[n]为n个点构成 ...

  7. [2016北京集训试题15]cot-[分块]

    Description Solution 如图,假如我们知道了以任何一个点为顶点的135-180度的前缀和和90-180度的前缀和,我们就可以搞出三角形的面积. 差分.add[i][j]和dev[i] ...

  8. [2016北京集训试题15]项链-[FFT]

    Description Solution 设y[i+k]=y[i]+n. 由于我们要最优解,则假如将x[i]和y[σ[i]]连线的话,线是一定不会交叉的. 所以,$ans=\sum (x_{i}-y_ ...

  9. [2016北京集训试题14]股神小D-[LCT]

    Description Solution 将(u,v,l,r)换为(1,u,v,l)和(2,u,v,r).进行排序(第4个数为第一关键字,第1个数为第二关键字).用LCT维护联通块的合并和断开.(维护 ...

随机推荐

  1. css属性之flex属性

    flex属性 规定了弹性元素如何伸长或缩短以适应flex容器中的可用空间.是一个简写属性,可以同时设置flex-grow, flex-shrink, flex-basis三个子属性. /* Basic ...

  2. idea更新maven依赖包

    IntelljIdea 自动载入Maven依赖的功能很好用,但有时候会碰到问题,导致pom文件修改却没有触发自动重新载入的动作,此时需要手动强制更新依赖. 如下: (1)右键单击项目: (2)在弹出菜 ...

  3. 数据类型.md

    数据类型 整型 数据类型 含义(有符号) tinyint(m) 1个字节 范围(-128~127) smallint(m) 2个字节 范围(-32768~32767) mediumint(m) 3个字 ...

  4. C# winform 数据库操作知识点总结(干货)

    1.数据库连接及操作 在说数据库操作之前,先说一下数据库连接操作字符串的获取 首先,点击服务器资源管理器,接下来选中数据连接右键点击添加连接,填入你要连接的服务器名称,点击单选框使用SQL Serve ...

  5. [Python 网络编程] TCP Client (四)

    TCP Client 客户端编程步骤: 创建socket对象 连接到服务端的ip和port,connect()方法 传输数据 使用send.recv方法发送.接收数据 关闭连接,释放资源 最简单的客户 ...

  6. 一起玩树莓派3+使用Gitlab搭建专业Git服务

    http://bbs.eeworld.com.cn/thread-505256-1-1.html https://packages.gitlab.com/gitlab/raspberry-pi2 ht ...

  7. Filters in ASP.NET Core (转自MSDN)

    Filters in ASP.NET Core MVC allow you to run code before or after specific stages in the request pro ...

  8. linux文件系统写过程简析

    linux写入磁盘过程经历VFS ->  页缓存(page cache) -> 具体的文件系统(ext2/3/4.XFS.ReiserFS等) -> Block IO ->设备 ...

  9. Datatable报错Uncaught TypeError: Cannot read property 'cell' of undefined

    使用Datatables时,报出错误 仔细想想,是因为我在columns里加入了id,并设置visible:false 但是却没在下面的HTML部分多加一个 th 虽然我觉得因为id是隐藏的,不用加上 ...

  10. 怎样在Win7系统中搭建Web服务器

    一.搭建web服务 1.打开控制面板,选择并进入“程序”,双击“打开或关闭Windows服务”,在弹出的窗口中选择“Internet信息服务”下面所有的选项,点击确定后,开始更新服务. 2.更新完成后 ...