洛谷

Codeforces


根号分治真是妙啊。


思路

考虑对于单独的一个\(k\)如何计算答案。

与“赛道修建”非常相似,但那题要求边,这题要求点,所以更加简单。

在每一个点贪心地把子树升上来的两条最长的链拼在一起,能组就组,否则把最长链往上送,复杂度\(O(n)\)。

那么多个\(k\)怎么办呢?

分析一波,\(k<\sqrt{n}\)时可以暴力计算,而\(k>\sqrt{n}\)时\(ans_k\leq \lfloor \frac{n}{k}\rfloor\),只有\(\sqrt{n}​\)种取值。

显然\(ans\)单调不增,所以可以二分边界,复杂度\(O(n\sqrt{n}\log n)\)。

把界限调为\(\sqrt{n\log n}\)后复杂度可以优化至\(O(n\sqrt{n\log n})\)。

然而我这么写T掉了……

发现网上还有一种整体二分的写法,不知为何跑的飞快……只能改成整体二分了……


代码

注释掉的是根号分治的代码,求找错\(Q\omega Q\)

#include<bits/stdc++.h>
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define sz 101010
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
template<typename T>inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
template<typename T>inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
void file()
{
#ifndef ONLINE_JUDGE
freopen("a.txt","r",stdin);
#endif
}
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std; int n;
struct hh{int t,nxt;}edge[sz<<1];
int head[sz],ecnt;
void make_edge(int f,int t)
{
edge[++ecnt]=(hh){t,head[f]};
head[f]=ecnt;
edge[++ecnt]=(hh){f,head[t]};
head[t]=ecnt;
} int K;
int f[sz];
int id[sz],fa[sz],cnt;
#define v edge[i].t
void dfs(int x,int fa)
{
::fa[x]=fa;
go(x) if (v!=fa) dfs(v,x);
id[++cnt]=x;
}
int check(int len)
{
K=len;
int ret=0;
rep(i,1,n)
{
int x=id[i],mx1=0,mx2=0;
go(x) if (v!=fa[x])
{
if (f[v]>mx1) mx2=mx1,mx1=f[v];
else if (f[v]>mx2) mx2=f[v];
}
if (mx1+mx2+1>=K) ++ret,f[x]=0;
else f[x]=mx1+1;
}
return ret;
}
#undef v int ans[sz]; void solve(int l,int r,int L,int R)
{
if (r<l) return;
if (L==R) { rep(i,l,r) ans[i]=L; return; }
int mid=(l+r)>>1,s=check(mid);
ans[mid]=s;
solve(l,mid-1,s,R),solve(mid+1,r,L,s);
} int main()
{
file();
read(n);
int x,y;
rep(i,1,n-1) read(x,y),make_edge(x,y);
dfs(1,0);
/*
int T=sqrt(n*log2(n));
rep(i,1,T) ans[i]=check(i);
int las=T;
drep(i,n/T,0)
{
int l=las+1,r=n,R=-1;
while (l<=r)
{
int mid=(l+r)>>1;
if (check(mid)>=i) R=mid,l=mid+1;
else r=mid-1;
}
rep(j,las+1,R) ans[j]=i;
las=max(las,R);
}
rep(i,1,n) printf("%d\n",ans[i]);
*/
solve(1,n,0,n);
rep(i,1,n) printf("%d\n",ans[i]);
return 0;
}

Codeforces 1039D You Are Given a Tree [根号分治,整体二分,贪心]的更多相关文章

  1. CF1039D You Are Given a Tree 根号分治、二分、贪心

    传送门 似乎直接做不太好做-- 当你不会做的时候就可以考虑根号算法了(或许是这样的 考虑如果只有一个询问如何计算答案. 显然是可以贪心的,思路与NOIP2018D1T3是相同的.每一个点向上传一条链, ...

  2. 【bzoj2506】calc 根号分治+STL-vector+二分+莫队算法

    题目描述 给一个长度为n的非负整数序列A1,A2,…,An.现有m个询问,每次询问给出l,r,p,k,问满足l<=i<=r且Ai mod p = k的值i的个数. 输入 第一行两个正整数n ...

  3. CF1039D You Are Given a Tree 根号分治,贪心

    CF1039D You Are Given a Tree LG传送门 根号分治好题. 这题可以整体二分,但我太菜了,不会. 根号分治怎么考虑呢?先想想\(n^2\)暴力吧.对于每一个要求的\(k\), ...

  4. codeforces 1065F Up and Down the Tree

    题目链接:codeforces 1065F Up and Down the Tree 题意:给出一棵树的节点数\(n\)以及一次移动的最大距离\(k\),现在有一个标记在根节点1处,每一次可以进行一下 ...

  5. Codeforces 914H Ember and Storm's Tree Game 【DP】*

    Codeforces 914H Ember and Storm's Tree Game 题目链接 ORZ佬 果然出了一套自闭题 这题让你算出第一个人有必胜策略的方案数 然后我们就发现必胜的条件就是树上 ...

  6. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  7. CF804D Expected diameter of a tree 树的直径 根号分治

    LINK:Expected diameter of a tree 1e5 带根号log 竟然能跑过! 容易想到每次连接两个联通快 快速求出直径 其实是 \(max(D1,D2,f_x+f_y+1)\) ...

  8. [CF1039D]You Are Given a Tree[贪心+根号分治]

    题意 给你\(n\)个点的树,其中一个简单路径的集合被称为\(k\)合法当且仅当树的每个节点最多属于一条路径,且每条路径包含\(k\)个节点.对于每个\(k(k \in [1,n])\),输出最多的\ ...

  9. CF1039D-You Are Given a Tree【根号分治,贪心】

    正题 题目链接:https://www.luogu.com.cn/problem/CF1039D 题目大意 给出\(n\)个点的一棵树,然后对于\(k\in[1,n]\)求每次使用一条长度为\(k\) ...

随机推荐

  1. Newtonsoft.Json序列化Enum类型

    [JsonConverter(typeof(StringEnumConverter))] public StringAlignment TextAlign { get => textAlign; ...

  2. NSScanner类的基本用法

    NSScanner是一个类,用于在字符串中扫描指定的字符,尤其是把它们翻译/转换为数字和别的字符串.可以在创建NSScaner时指定它的string属性,然后scanner会按照你的要求从头到尾地扫描 ...

  3. luogu P3241 [HNOI2015]开店

    传送门 (下面记年龄为\(a_x\))题目要求的是\[\sum_{x=1}^{n} [a_x\in [l,r]]*dis(x,u)=\sum_{x=1}^{n} [a_x\in [l,r]]*de_x ...

  4. MFCC/Filter Bank的提取流程

    预加重:通过一个一阶有限激励响应高通滤波器,使信号的频谱变得平坦,不易受到有限字长效应的影响. 分帧:根据语音的短时平稳特性,语音可以以帧为单位进行处理,实验中选取的语音帧长为32ms,帧移为16ms ...

  5. 谈谈jQuery中的数据类型检测

    这次是分享jQuery代码中的一些简写技巧,分析jQuery是如何优化代码的,如何用最少的代码来实现jQuery. 在我们工作中也常常会遇到一些数据类型检测,一些方法调用的形式 1 var arr = ...

  6. ASP.NET EF 延迟加载,导航属性延迟加载

    ASP.NET EF 延迟加载,导航属性延迟加载   EF(EntityFramework)原理:属于ORM的一种实现 通过edmx文件来查看三部分:概念模型,数据模型,映射关系,上下文DbConte ...

  7. 第一章 Android系统的编译和移植实例

    第一章 Android系统的编译和移植实例 这一章节主要介绍了Android系统的编译和移植技术,作为建立在Linux内核的基础上的Android操作系统,它的编译和移植不论在过程还是技术方面都和嵌入 ...

  8. (7)Java数据结构--集合map,set,list详解

    MAP,SET,LIST,等JAVA中集合解析(了解) - clam_clam的专栏 - CSDN博---有颜色, http://blog.csdn.net/clam_clam/article/det ...

  9. 对象转换为json格式,类似中间层API

    <一头扎进SpringMvc视频教程\<一头扎进SpringMvc>第四讲 源码\> 对象自动转换为json格式要在 spring-mvc.xml添加一个东西 ,和对应的命名空 ...

  10. 关于VXLAN的认识-----基础知识

    一.什么是VXLAN 普通的VLAN数量只有4096个,无法满足大规模云计算IDC的需求,因为目前大部分IDC内部结构主要分为两种L2,L3. L2结构里面,所有的服务器都在一个大的局域网里面,TOR ...