题意:求树上距离为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. python 基础 3.2 文件 for 练习

    #/usr/bin/python #coding=utf-8 #@Time   :2017/11/1 22:19 #@Auther :liuzhenchuan #@File   :1030-1031练 ...

  2. Sqlite 设置外键级联更新

    Sqlite 设置外键级联更新 选择好外键表和列以后,勾选更新事件,更新方式设置为CASCADE,即可在外键更新时自动更新

  3. 发送邮件 Email(java实现)

    //发送邮件 private static void sendMail(String mail, String mailContext) { try { //获取文本中html的内容 并动态替换并显示 ...

  4. JAVA数据类型(转)

     java中数据的基本类型分为: 基本数据类型和引用数据类型,对此不多介绍:   接下来讨论一下java中数据类型存储在哪     基本数据类型存储在哪,取决于基本类型在哪声明:          1 ...

  5. 采集练习(十) php 获得电视节目预告---数据来自搜视网

    前几天逛湖南卫视,偶然间发现它的网站上也有节目预告,一看源码,居然是来自搜视网的xml,于是就想获得它的数据(页面直接ajax加载估计会有跨域问题) 前阵子也写过另一个方法获得 节目预告(采集练习(七 ...

  6. linux批量更改权限

    用命令 sudo chmod 777 -Rfv /home/name/* 注释:1.777 为 要修改成 的 文件的 权限:2.-R 是 子目录 下的 文件 也修改:3.-f 强制:4. -v是 显示 ...

  7. Java基础教程:多线程基础(4)——Lock的使用

    Java基础教程:多线程基础(4)——Lock的使用 快速开始 Java 5中Lock对象的也能实现同步的效果,而且在使用上更加方便. 本节重点的2个知识点是:ReentrantLock类的使用和Re ...

  8. Machine Learning No.11: Recommender System

    1. Content based Problem formulation Content Based Recommendations: 2. collaborative filtering algor ...

  9. centos或ubuntu下手动安装jdk8

    https://blog.csdn.net/pang_ping/article/details/80570011 https://blog.csdn.net/u012707739/article/de ...

  10. jQuery+CSS3动画相册特效

    在线演示 本地下载