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. luogu P3381【模板】最小费用最大流

    嘟嘟嘟 没错,我开始学费用流了! 做法也是比较朴素的\(spfa\). 就是每一次以费用为权值跑一遍\(spfa\)找到一条最短路,然后把这条道全流满,并把这一次的流量和费用累加到答案上.因此我们需要 ...

  2. Controller如何写的更简化

    Controller层相当于MVC中的C,也是安卓或者前端请求的接口. 首先说Controller为什么需要写的更加简化? 第一.Controller是不能复用的: 第二.即便是将Controller ...

  3. PAT——1029. 旧键盘

    旧键盘上坏了几个键,于是在敲一段文字的时候,对应的字符就不会出现.现在给出应该输入的一段文字.以及实际被输入的文字,请你列出肯定坏掉的那些键. 输入格式: 输入在2行中分别给出应该输入的文字.以及实际 ...

  4. poj 2253 Frogger 最小瓶颈路(变形的最小生成树 prim算法解决(需要很好的理解prim))

    传送门: http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissi ...

  5. POJ 1182 食物链(经典带权并查集 向量思维模式 很重要)

    传送门: http://poj.org/problem?id=1182 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: ...

  6. Linux 带宽、CPU、内存占用情况

    iftop 查看带宽占用情况(总)yum install -y iftop 安装iftopnethogs 查看进程流量 curl http://218.5.73.233:8060/ip.php 查看出 ...

  7. zookeeper启动时报错:Error contacting service. It is probably not running问题

    查看zookeeper.out发现启动日志报错未找到java路径. 启动日志位于zookeeper-4.0.10/bin目录下 修改/etc/profile中环境变量得以解决.

  8. mongodb分组函数的使用(spring-data-mongodb)

    这两天要做mongodb日志的模块,下面记录一下. 一. 首先要导入一批数据,使用springboot来完成. 配置mongodb的复制集:在application.yml文件中配置uri来完成 格式 ...

  9. 如何设计处优秀的Restful API

    只知道遵规循矩的程序员是假程序员,任何技术都是不断发明创造改进的. 如何设计处优秀的Restful API?  盲目跟风,设计糟糕的Resful API = 浪费时间 ! 不啰嗦,直接进入技术主题: ...

  10. L2-006 树的遍历 (后序中序求层序)

    题目: 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历的序列.这里假设键值都是互不相等的正整数. 输入格式: 输入第一行给出一个正整数N(≤30),是二叉树中结点的个数.第二行给出其后序遍历序 ...