传送门

代码:

长链剖分好题。

题意:给你一棵树,问树上选三个互不相同的节点,使得这个三个点两两之间距离相等的方案数。


思路:

先考虑dpdpdp。

fi,jf_{i,j}fi,j​表示iii子树中离iii距离为jjj的点数,gi,jg_{i,j}gi,j​表示iii子树中所有满足dist(lca(u,v),i)−dist(lca(u,v),i)=jdist(lca(u,v),i)-dist(lca(u,v),i)=jdist(lca(u,v),i)−dist(lca(u,v),i)=j的点对数。

不难发现这两个状态是可以进行拼接的。

因此对于一对父亲和孩子(p,v)(p,v)(p,v)有如下转移式:

ans+=gv,i+1∗fp,i+gp,i∗fv,i−1ans+=g_{v,i+1}*f_{p,i}+g_{p,i}*f_{v,i-1}ans+=gv,i+1​∗fp,i​+gp,i​∗fv,i−1​

gp,i+=gv,i−1+fv,i−1∗fp,ig_{p,i}+=g_{v,i-1}+f_{v,i-1}*f_{p,i}gp,i​+=gv,i−1​+fv,i−1​∗fp,i​

fp,i+=fv,i−1f_{p,i}+=f_{v,i-1}fp,i​+=fv,i−1​

然后用长链剖分优化一下即可。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
	int ans=0;
	char ch=getchar();
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
	return ans;
}
typedef long long ll;
const int N=1e5+5;
vector<int>e[N];
int n,hson[N],dep[N],mdep[N],len[N],fa[N];
ll tmp[N<<2],*f[N],*g[N],*now=tmp,ans=0;
void dfs1(int p){
	for(ri i=0,v;i<e[p].size();++i){
		if((v=e[p][i])==fa[p])continue;
		fa[v]=p,dep[v]=mdep[v]=dep[p]+1,dfs1(v),mdep[p]=max(mdep[p],mdep[v]);
		if(mdep[v]>mdep[hson[p]])hson[p]=v;
	}
	len[p]=mdep[p]-dep[p]+1;
}
void dfs2(int p){
	if(hson[p])f[hson[p]]=f[p]+1,g[hson[p]]=g[p]-1,dfs2(hson[p]);
	f[p][0]=1,ans+=g[p][0];
	for(ri i=0,v;i<e[p].size();++i){
		if((v=e[p][i])==fa[p]||v==hson[p])continue;
		f[v]=now,now+=2*len[v],g[v]=now,now+=2*len[v],dfs2(v);
		for(ri j=0;j<len[v];++j){
			ans+=f[v][j]*g[p][j+1];
			if(j)ans+=g[v][j]*f[p][j-1];
		}
		for(ri j=0;j<len[v];++j){
			g[p][j+1]+=f[v][j]*f[p][j+1];
			if(j)g[p][j-1]+=g[v][j];
			f[p][j+1]+=f[v][j];
		}
	}
}
int main(){
	freopen("lx.in","r",stdin);
	while(n=read(),n){
		ans=0;
		memset(tmp,0,sizeof(tmp));
		memset(hson,0,sizeof(hson));
		memset(mdep,0,sizeof(mdep));
		for(ri i=1;i<=n;++i)e[i].clear();
		for(ri i=1,u,v;i<n;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
		dfs1(1),now=tmp,f[1]=now,now+=2*len[1],g[1]=now,now+=2*len[1],dfs2(1),cout<<ans<<'\n';
	}
	return 0;
}

2019.01.08 bzoj4543: [POI2014]Hotel加强版(长链剖分+dp)的更多相关文章

  1. 【BZOJ4543】[POI2014]Hotel加强版 长链剖分+DP

    [BZOJ4543][POI2014]Hotel加强版 Description 同OJ3522数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 ...

  2. bzoj4543 [POI2014]Hotel加强版 长链剖分+树形DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4543 题解 这道题的弱化版 bzoj3522 [POI2014]Hotel 的做法有好几种吧. ...

  3. BZOJ4543[POI2014]Hotel加强版——长链剖分+树形DP

    题意参见BZOJ3522 n<=100000 数据范围增强了,显然之前的转移方程不行了,那么不妨换一种. 因为不能枚举根来换根DP,那么我们描述的DP方程每个点要计算三个点都在这个点的子树内的方 ...

  4. BZOJ.4543.[POI2014]Hotel加强版(长链剖分 树形DP)

    题目链接 弱化版:https://www.cnblogs.com/SovietPower/p/8663817.html. 令\(f[x][i]\)表示\(x\)的子树中深度为\(i\)的点的个数,\( ...

  5. BZOJ3522&4543 [POI2014]Hotel加强版 长链剖分

    上上周见fc爷用长链剖分秒题 于是偷偷学一学 3522的数据范围很小 可以暴力枚举每个点作为根节点来dp 复杂度$O(n^2)$ 考虑令$f[x][j]$表示以$x$为根的子树内距离$x$为$j$的点 ...

  6. BZOJ4543 POI2014 Hotel加强版 【长链剖分】【DP】*

    BZOJ4543 POI2014 Hotel加强版 Description 同OJ3522 数据范围:n<=100000 Sample Input 7 1 2 5 7 2 5 2 3 5 6 4 ...

  7. 【LOJ】#3014. 「JOI 2019 Final」独特的城市(长链剖分)

    LOJ#3014. 「JOI 2019 Final」独特的城市(长链剖分) 显然我们画一条直径,容易发现被统计的只可能是直径某个距离较远的端点到这个点的路径上的值 用一个栈统计可以被统计的点,然后我们 ...

  8. BZOJ4543 [POI2014]Hotel加强版

    题意 有一个树形结构,每条边的长度相同,任意两个节点可以相互到达.选3个点.两两距离相等.有多少种方案? 数据范围:n<=100000 分析 参照小蒟蒻yyb的博客. 我们先考虑一个\(O(n^ ...

  9. 219.01.19 bzoj3252: 攻略(长链剖分+贪心)

    传送门 长链剖分好题. 题意:给一棵带点权的树,可以从根节点到任一叶节点走kkk次,走过的点只能计算一次,问kkk次走过的点点权值和最大值. 思路: 考虑将整棵树带权长链剖分,这样链与链之间是不会重复 ...

随机推荐

  1. Kylin 与 Spark SQL相比,有哪些差异和优势

    SparkSQL本质上是基于DAG模型的MPP.而Kylin核心是Cube(多维立方体).关于MPP和Cube预处理的差异,重复如下: > MPP [1] 的基本思路是增加机器来并行计算,从而提 ...

  2. swift - 本地通知

    1. AppDelegate  注册 class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? fun ...

  3. django static 无法正确加载目录下的css

    在static->web目录下添加CSS后该css文件一直报404错误,解决问题: 在setting.py文件添加: STATICFILES_DIRS = [ os.path.join(BASE ...

  4. DMZ原理与应用

    DMZ是英文“demilitarized zone”的缩写,中文名称为“隔离区”,“非军事化区”.它是为了解决安装防火墙后外部网络不能访问内部网络服务器的问题,而设立的一个非安全系统与安全系统之间的缓 ...

  5. 17-matlab例题练习

      练习 %编写程序使任意输入的一个数反转,如输入123456,输出654321 clc,clear; a = input('输入一个整数\n'); b = 0; while a ~= 0 b = b ...

  6. 运行./build.sh出现错误:bash: ./build.sh: Permission denied

    原因:文件为只读,或者用户没有权限. 修改方法:   运行命令: chmod 777 build.sh

  7. .net如何处理高并发socket,建立高性能健壮的socket服务

    看到一个问题,说如何保持5000-10000+的健壮的socket服务. 初学者肯定是会把每个连接都开一个线程来监听.这很浪费资源 通常只会(动态地)占用几个线程就能保持3000个长连接会话了.“为每 ...

  8. JAVA程序 从命令行接受多个数字,求和之后输出结果

    源程序代码: public class sum{ public static void main(String[] args){ double[] a=new double[4]; a[0]=Doub ...

  9. glide install失败 Update failed for golang.org/x/net: Cannot detect VCS

    失败信息: [WARN]    Unable to checkout golang.org/x/net[ERROR]    Update failed for golang.org/x/net: Ca ...

  10. git-flow 备忘清单

    原文地址:http://danielkummer.github.io/git-flow-cheatsheet/index.zh_CN.html