题意:求树上距离为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. vue-cli3.0升级失败,vue-cli卸载不掉,vue-cli升级不了3.0

    https://juejin.im/post/5bf7d67c51882518805acb1a vue-cli3.0 使用图形化界面创建和管理项目

  2. 一种微信直播H5直播与存储回放的HLS摄像机方案

    接上篇 在上一篇博客<一种流量成本节省60%以上的手机直播微信直播H5直播幼儿园直播方案>中,我们一共介绍了两种省钱的HLS直播途径: 方案一:编码器或者内网推流直接对接云存储的场景 如果 ...

  3. Vue中div高度自适应

    Vue中尽量不使用dom的高度计算 <template> <div :style="conheight"> </template> <sc ...

  4. sort()函数到底是怎样进行数字排序的

    很多人会用sort(),并不见得知道它具体是怎样给数字排序的.其实不知道也行,会用就可以,感兴趣的可以来看看. var numberArray = [2,4,1,3]; numberArray.sor ...

  5. 【题解】[P4178 Tree]

    [题解]P4178 Tree 一道点分治模板好题 不知道是不是我见到的题目太少了,为什么这种题目都是暴力开值域的桶QAQ?? 问点对,考虑点分治吧.直接用值域树状数组开下来,统计的时候直接往树状数组里 ...

  6. 网络新闻传输协议NNTP

    一.Usenet与新闻组 Usenet新闻系统是一个全球存档的“电子公告板”,各种主题的新闻组一应俱全.新闻组可以是面向全球泛泛而谈,也可以是只面向某一个地区区域. 整个系统是由一个大量计算机组成的一 ...

  7. Java for LeetCode 125 Valid Palindrome

    Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignori ...

  8. Java for LeetCode 117 Populating Next Right Pointers in Each Node II

    Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...

  9. 微信小程序开发:学习笔记[4]——样式布局

    微信小程序开发:学习笔记[4]——样式布局 Flex布局 新的布局方式 在小程序开发中,我们需要考虑各种尺寸终端设备上的适配.在传统网页开发,我们用的是盒模型,通过display:inline | b ...

  10. dojo 官方翻译 dojo/_base/lang 版本1.10

    官方地址:http://dojotoolkit.org/reference-guide/1.10/dojo/_base/lang.html#dojo-base-lang 应用加载声明: require ...