题意:求树上距离为k的点对个数;

解题关键:练习一下点分治不用容斥 而直接做的做法。注意先查询,后更新。

不过这个方法有个缺陷,每次以一个新节点为根,必须memset mp数组,或许使用map会好些,更新序号一类用ca这种形式更好些。

试了一下,map更慢,应该是带log的原因。

点分治解法:

 #pragma comment(linker,"/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<map>
#define maxn 100040
#define maxm 1000500
using namespace std;
typedef long long ll;
const ll mod=;
const ll inf=1ll<<;
ll n,k,ans,size,s[maxn],f[maxn],path[maxn],cr;
ll head[maxn],cnt,root;
bool vis[maxn];
struct edge{
ll to,nxt;
}e[maxn<<];
map<int,int>mp;
void add_edge(ll u,ll v){
e[cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt++;
} inline ll read(){
char k=;char ls;ls=getchar();for(;ls<''||ls>'';k=ls,ls=getchar());
ll x=;for(;ls>=''&&ls<='';ls=getchar())x=(x<<)+(x<<)+ls-'';
if(k=='-')x=-x;return x;
} void get_root(ll u,ll fa){//get_root会用到size
s[u]=;f[u]=;//f是dp数组
for(ll i=head[u];i!=-;i=e[i].nxt){
ll v=e[i].to;
if(v==fa||vis[v]) continue;
get_root(v,u);
s[u]+=s[v];
f[u]=max(f[u],s[v]);
}
f[u]=max(f[u],size-s[u]);
root=f[root]>f[u]?u:root;
} void get_path_size(ll u,ll fa,ll dis){
if(dis+<=k){
path[cr]=dis+;
cr++;
}
s[u]=;
for(ll i=head[u];i!=-;i=e[i].nxt){
ll v=e[i].to;
if(v==fa||vis[v]) continue;
get_path_size(v,u,dis+);
s[u]+=s[v];
}
} void work(ll u,ll fa){
vis[u]=true;
mp.clear();
mp[]=;
for(ll i=head[u];i!=-;i=e[i].nxt){
ll v=e[i].to;
if(v==fa||vis[v]) continue;
cr=;
get_path_size(v,u,);
for(ll j=;j<cr;j++){
ans+=mp[k-path[j]];
}
for(int j=;j<cr;j++){
mp[path[j]]++;
}
}
for(ll i=head[u];i!=-;i=e[i].nxt){
ll v=e[i].to;
if(vis[v]||v==fa) continue;
size=s[v],root=;
get_root(v,u);
work(root,u);
}
} void init(){
memset(vis,,sizeof vis);
memset(head,-,sizeof head);
ans=cnt=;
} int main(){
ll a,b;
f[]=inf;
while(scanf("%I64d%I64d",&n,&k)!=EOF){
init();
for(int i=;i<n-;i++){
a=read(),b=read();
add_edge(a,b);
add_edge(b,a);
}
size=n,root=;
get_root(,-);
work(root,-);
printf("%d\n",ans);
}
return ;
}

树形dp解法:

复杂度:$O(nk)$

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define maxn 100006
int head[maxn],cnt,dp[maxn][];
struct edge{
int to,w,nxt;
}e[maxn<<];
ll ans;
int n,k,a,b;
void add_edge(int u,int v){
e[cnt].to=v;
e[cnt].nxt=head[u];
head[u]=cnt++;
} void dfs(int u,int fa){
dp[u][]=;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
dfs(v,u);
for(int j=;j<=k;j++){
dp[u][j]+=dp[v][j-];
}
}
ans+=dp[u][k];
int tmp=;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
for(int j=;j<k;j++){
tmp+=1ll*dp[v][j-]*(dp[u][k-j]-dp[v][k-j-]);
}
}
ans+=tmp/;
} void init(){
memset(head,-,sizeof head);
cnt=;
ans=;
} int main(){
init();
cin>>n>>k;
for(int i=;i<n-;i++){
cin>>a>>b;
add_edge(a,b);
add_edge(b,a);
}
dfs(,-);
cout<<ans<<"\n";
return ;
}

[codeforces161D]Distance in Tree(点分治/树形dp)的更多相关文章

  1. 『You Are Given a Tree 整体分治 树形dp』

    You Are Given a Tree Description A tree is an undirected graph with exactly one simple path between ...

  2. POJ 1741.Tree 树分治 树形dp 树上点对

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 24258   Accepted: 8062 Description ...

  3. Codeforces 791D Bear and Tree Jump(树形DP)

    题目链接 Bear and Tree Jumps 考虑树形DP.$c(i, j)$表示$i$最少加上多少后能被$j$整除. 在这里我们要算出所有$c(i, k)$的和. 其中$i$代表每个点对的距离, ...

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

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

  5. E. Alternating Tree 树点分治|树形DP

    题意:给你一颗树,然后这颗树有n*n条路径,a->b和b->a算是一条,然后路径的权值是 vi*(-1)^(i+1)  注意是点有权值. 从上头往下考虑是点分治,从下向上考虑就是树形DP, ...

  6. Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF980F.html 题目传送门 - CF980F 题意 给定一个 $n$ 个节点 $m$ 条长为 $1$ 的边 ...

  7. hdu5293 Tree chain problem 树形dp+线段树

    题目:pid=5293">http://acm.hdu.edu.cn/showproblem.php?pid=5293 在一棵树中,给出若干条链和链的权值.求选取不相交的链使得权值和最 ...

  8. [BZOJ2152]聪聪可可 点分治/树形dp

    2152: 聪聪可可 Time Limit: 3 Sec  Memory Limit: 259 MB Submit: 3602  Solved: 1858 [Submit][Status][Discu ...

  9. CodeChef - PRIMEDST Prime Distance On Tree 树分治 + FFT

    Prime Distance On Tree Problem description. You are given a tree. If we select 2 distinct nodes unif ...

随机推荐

  1. C# Array类的浅复制Clone()与Copy()的差别

    1 Array.Clone方法 命名空间:System 程序集:mscorlib 语法: public Object Clone() Array的浅表副本仅复制Array的元素,不管他们是引用类型还是 ...

  2. urllib与urllib2的学习总结(python2.7.X): python urllib与urllib2

    https://www.cnblogs.com/wly923/archive/2013/05/07/3057122.html

  3. 基于红帽5裁剪一个简单的Linux

    HOST:宿主机 Target:目标机 1.基于HOST制作一个简单的可启动的Linux 1.给目标磁盘分区 两个: 在宿主机上:/dev/sdb1,/dev/sdb2 /dev/sdb1挂载到 /m ...

  4. EasyDSS RTMP流媒体解决方案之Windows服务安装方案

    Windows服务安装 EasyDSS_Solution流媒体解决方案,可以通过start一键启动.在实际应用中,我们希望可以设置成系统服务,那么下面我将会介绍,如何在windows中将流媒体解决方案 ...

  5. web无插件播放RTSP摄像机方案,拒绝插件,拥抱H5!

    本文转自:http://www.cnblogs.com/babosa/p/7355468.html 需求 问题:有没有flash播放RTSP的播放器?H5能不能支持RTSP播放? 答案:没见过,以后估 ...

  6. 配置springMVC时出现的问题

    配置springMVC时出现的问题 项目结构如图:

  7. mongo数据库中一条记录中某个属性是数组情形时 数据结构的定义

    package entity; import java.util.Date; import com.mongodb.BasicDBList;import com.mongodb.DBObject; p ...

  8. 我的Java开发学习之旅------>Java String对象作为参数传递的问题解惑

    又是一道面试题,来测试你的Java基础是否牢固. 题目:以下代码的运行结果是? public class TestValue { public static void test(String str) ...

  9. 一起来学linux:shell script(二)关于脚本

    (一)首先来看shell脚本的执行方式,shell脚本的后缀名都是sh文件. 1 sh test.sh 2 source test.sh 这两种方式有什么区别呢.test.sh 里的脚本很简单, 从键 ...

  10. (转) 在linux网络UDP通信中,关于客户端是否绑定的理解

    最近在做一个实例,是用RTSP协议完成.服务器已经有了,只需要把客户端做好就行了,在做的过程中发现了一些问题,就是关于UDP客户端是否绑定的问题. 也许大家在书上看到的大多都是说UDP客户端不需要绑定 ...