题目

给定一棵树,对于 \(k\in [1,n]\) 问最多可以分成多少段长度为 \(k\) 的不交路径


分析

首先考虑对于单个 \(k\) 怎么做。

设 \(dp[x]\) 表示点 \(x\) 往下最多能伸出多长,那么 \(dp[x]=\max\{dp[y]+1\}\)。

如果 \(dp[x]+dp[y]\geq k\) 那么标记 \(x\) 这个点不能再选,这样贪心显然是正确的。

但是 \(O(n^2)\) 显然是不能接受的,考虑大于 \(\sqrt{n}\) 的部分答案一定小于 \(\sqrt{n}\)

那可以在根号内直接树形dp,根号外由于产生了很多相同段,直接二分即可。

时间复杂度为 \(O(nT+\frac{n^2\log n}{T})\) 当 \(T\) 取 \(\sqrt{n}\log{n}\) 时最优。


代码

#include <cstdio>
#include <cctype>
#include <cmath>
using namespace std;
const int N=100011;
struct node{int y,next;}e[N<<1];
int qp[N],fat[N],as[N],et=1,dp[N],ans[N],n,Top,bl;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
void Max(int &a,int b){a=a>b?a:b;}
void dfs(int x,int fa){
for (int i=as[x];i;i=e[i].next)
if (e[i].y!=fa) dfs(e[i].y,x);
qp[++Top]=x,fat[x]=fa;
}
int answ(int k){
if (~ans[k]) return ans[k]; ans[k]=0;
for (int i=1;i<=n;++i) dp[i]=1;
for (int i=1;i<n;++i)
if (dp[qp[i]]>0&&dp[fat[qp[i]]]>0){
if (dp[fat[qp[i]]]+dp[qp[i]]>=k)
++ans[k],dp[fat[qp[i]]]=-1;
else Max(dp[fat[qp[i]]],dp[qp[i]]+1);
}
return ans[k];
}
int main(){
n=iut(),bl=sqrt(n*log(n)/log(2));
for (int i=1;i<=n;++i) ans[i]=-1;
for (int i=1;i<n;++i){
int x=iut(),y=iut();
e[++et]=(node){y,as[x]},as[x]=et;
e[++et]=(node){x,as[y]},as[y]=et;
}
dfs(1,0),ans[1]=n;
for (int i=2;i<=bl;++i) ans[i]=answ(i);
for (int l=bl+1;l<=n;++l){
int _l=l,r=n,now=answ(l);
while (l<r){
int mid=(l+r+1)>>1;
if (answ(mid)==now) l=mid;
else r=mid-1;
}
for (int j=_l;j<=l;++j) ans[j]=now;
}
for (int i=1;i<=n;++i) print(ans[i]),putchar(10);
return 0;
}

#根号分治,树形dp#CF1039D You Are Given a Tree的更多相关文章

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

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

  2. [codeforces161D]Distance in Tree(点分治/树形dp)

    题意:求树上距离为k的点对个数: 解题关键:练习一下点分治不用容斥 而直接做的做法.注意先查询,后更新. 不过这个方法有个缺陷,每次以一个新节点为根,必须memset mp数组,或许使用map会好些, ...

  3. BZOJ 2152 / Luogu P2634 [国家集训队]聪聪可可 (点分治/树形DP)

    题意 一棵树,给定边权,求满足两点之间的路径上权值和为3的倍数的点对数量. 分析 点分治板题,对每个重心求子树下面的到根的距离模3分别为0,1,2的点的个数就行了. O(3nlogn)O(3nlogn ...

  4. [集训队作业2018]蜀道难——TopTree+贪心+树链剖分+链分治+树形DP

    题目链接: [集训队作业2018]蜀道难 题目大意:给出一棵$n$个节点的树,要求给每个点赋一个$1\sim n$之内的权值使所有点的权值是$1\sim n$的一个排列,定义一条边的权值为两端点权值差 ...

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

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

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

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

  7. BZOJ4182 Shopping(点分治+树形dp)

    点分治,每次考虑包含根的连通块,做树形多重背包即可,dfs序优化.注意题面给的di范围是假的,坑了我0.5h,心态炸了. #include<iostream> #include<cs ...

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

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

  9. BZOJ5341[Ctsc2018]暴力写挂——边分治+虚树+树形DP

    题目链接: CSTC2018暴力写挂 题目大意:给出n个点结构不同的两棵树,边有边权(有负权边及0边),要求找到一个点对(a,b)满足dep(a)+dep(b)-dep(lca)-dep'(lca)最 ...

  10. [WC2018]通道——边分治+虚树+树形DP

    题目链接: [WC2018]通道 题目大意:给出三棵n个节点结构不同的树,边有边权,要求找出一个点对(a,b)使三棵树上这两点的路径权值和最大,一条路径权值为路径上所有边的边权和. 我们按照部分分逐个 ...

随机推荐

  1. less变量书写及样式混入

    定义变量 定义混入样式 变量及混入样式使用 样式文件中   ~@代表src

  2. django学习第四天----mark_safe的用法,静态文件配置,用指令创建django项目应用注意点,ORM介绍,创建表执行命令,模板渲染补充(组件),inclusion_tag 自定义标签

    补充第三天跟safe差不多的一个方法 templatetags文件夹 自定义的py文件 需要先导入模块 from django.utils.safestring import mark_safe @r ...

  3. go-ini解析ini文件

    文档 https://github.com/go-ini/ini https://ini.unknwon.io/docs/intro/getting_started go get -u gopkg.i ...

  4. ASP.NET 通过拦截器记录错误日志

    前言 主要是记录一下实现的错误日志拦截,可以在拦截器里面控制返回的信息,把错误信息处理后返回给请求端. 代码实战 拦截器 /// <summary> /// 接口异常捕捉过滤器 /// & ...

  5. ABP模块签入GitLab后自动打包并推送到ProGet

    # 1.添加一个名为下划线的解决方案文件夹 # 2.把解决方案根目录下的几个必要的文件添加到上述文件夹下 # 3.修改NuGet.Config,添加私有NuGet服务器的网址,并配置用户名和密码: A ...

  6. STL-vector模拟实现

    #pragma once #include<assert.h> #include<iostream> using std::cout; using std::endl; usi ...

  7. opencv库图像基础1-python

    opencv库图像基础-python 基本操作 图片颜色通道 非灰度图的颜色通道是红绿蓝,在opencv中默认是BGR的顺序 argparse模块 argparse 库是 Python 标准库中用于命 ...

  8. 在Linux下开启指定端口号

    1.查看某个端口是否已开启,如果提示no表示未开启 #8888表示要查询的端口号firewall-cmd --query-port=8888/tcp 2.永久开启端口号,提示 success 表示成功 ...

  9. URLDNS链分析

    一.概述 URLDNS 是ysoserial中利用链的一个名字,通常用于检测是否存在Java反序列化漏洞.该利用链具有如下特点: 不限制jdk版本,使用Java内置类,对第三方依赖没有要求 目标无回显 ...

  10. left jon连接查询踩坑记

    项目开发中经常会使用到多张表进行关联查询,比如left join关联查询. 如果有一张表A和一张表B,查询语句 SELECT a.*,b.name from A a left join B b On ...