[2016北京集训试题7]thr-[树形dp+树链剖分+启发式合并]
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+树链剖分+启发式合并]的更多相关文章
- 【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 ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- 6.3 省选模拟赛 Decompose 动态dp 树链剖分 set
LINK:Decompose 看起来很难 实际上也很难 考验选手的dp 树链剖分 矩阵乘法的能力. 容易列出dp方程 暴力dp 期望得分28. 对于链的情况 容易发现dp方程可以转矩阵乘法 然后利用线 ...
- BZOJ4712洪水——动态DP+树链剖分+线段树
题目描述 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开了创造模式,然后飞到 山顶放了格水.于是小A面前出现了一个瀑布.作为平民的小A只好老实巴交地爬山堵水.那么 ...
- acm 2015北京网络赛 F Couple Trees 树链剖分+主席树
Couple Trees Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/problemset/problem/123 ...
- [2016北京集训试题8]连在一起的幻想乡[dp+无向图计数]
Description Solution 本博客参考yww大佬的博客,为了加深理解我就自己再写一遍啦. 以下的“无向图”均无重边无自环. 定义f0[n]为n个点构成的无向图个数,f1[n]为n个点构成 ...
- [2016北京集训试题15]cot-[分块]
Description Solution 如图,假如我们知道了以任何一个点为顶点的135-180度的前缀和和90-180度的前缀和,我们就可以搞出三角形的面积. 差分.add[i][j]和dev[i] ...
- [2016北京集训试题15]项链-[FFT]
Description Solution 设y[i+k]=y[i]+n. 由于我们要最优解,则假如将x[i]和y[σ[i]]连线的话,线是一定不会交叉的. 所以,$ans=\sum (x_{i}-y_ ...
- [2016北京集训试题14]股神小D-[LCT]
Description Solution 将(u,v,l,r)换为(1,u,v,l)和(2,u,v,r).进行排序(第4个数为第一关键字,第1个数为第二关键字).用LCT维护联通块的合并和断开.(维护 ...
随机推荐
- struts2中两个action之间的跳转(struts.xml)
1. action的配置中,有一个为"redirectAction”(重定向到一个Action)和chain(就是所谓的action请求链)的action类型顺便说一下struts2的act ...
- 第一篇markdown笔记
博客的样式设置 1 2 3 参考第一篇博客 参考第二篇博客 高效的写博客 博客园虽然支持markdown,但是好多快捷键都不支持,以后可以先在马克飞象上写好markdown笔记,再复制到博客上.
- xss实现获取网站源码
当网站cookie设置了httponly,xss获取不到到网站的cookie.但是我们是可以获取到网站后台的url. 这时候我们可以xss得到网站后台源码,从而找到网站后台的一些敏感操作:添加用户,删 ...
- pass语句
Python pass是空语句,是为了保持程序结构的完整性. pass 不做任何事情,一般用做占位语句. #!/usr/bin/python # -*- coding: UTF-8 -*- # 输出 ...
- 启动 NFS 守护进程:rpc.nfsd: writing fd to kernel failed: errno 111 (Connection refused)
启动 NFS 守护进程:rpc.nfsd: writing fd to kernel failed: errno 111 (Connection refused) rpc.nfsd: unable t ...
- C#利用反射动态创建对象 带参数的构造函数和String类型 (转载)
最近笔者有一个想法需要利用反射动态创建对象(如string,int,float,bool,以及自定义类等)来实现,一直感觉反射用不好,特别是当构造函数带参数的时候.MSDN上给出的例子十分复杂,网上的 ...
- Microsoft Visio / Project professional 2013 官方版本(下载)
Microsoft Visio微软开发的一款软件, 它有助于 IT 和商务专业人员轻松地可视化.分析和交流复杂信息. 它能够将难以理解的复杂文本和表格转换为一目了然的 Visio 图表. 该软件通过创 ...
- centos7 安装拼音输入法
依次选择Applications->System Tools->setting->Regiin&Language,添加Chinese(Intelligent Pinyin) ...
- 使用 runtime 实现字符串转方法,并传递参数
利用runtime的动态机制实现字符串转方法并传递参数 使用 SEL 关键字引用方法声明,使用 methodForSelector 寻找方法实现, 使用函数指针调用方法. - (void)action ...
- iOS-截取TableView生成图片
先看一下实例效果: 如果所示,这是一个在APP中截图,并调起微信客户端,发送给好友的例子,图片就是一个tableView的截图. 先实现一个小例子,如果tableVIew里面的内容,没有超过当前屏幕显 ...