CF1039D You Are Given a Tree

LG传送门

根号分治好题。

这题可以整体二分,但我太菜了,不会。

根号分治怎么考虑呢?先想想\(n^2\)暴力吧。对于每一个要求的\(k\),一遍dfs直接贪心,能拼成链就直接拼,正确性不用我证明吧。

考虑对于\(k \le \sqrt n\),直接按照暴力去做,复杂度\(O(n \sqrt n)\);对于\(k\)从\(\sqrt n+1\)到\(n\)的所有情况,我们发现答案只会在\(\sqrt n\)到\(0\)之间取值(\(k> \sqrt n\)),且是单调不升的,考虑用一个左往右移的指针来维护求解的过程,可以每次求出一段的值,具体来说是这样:先把指针\(i\)指向\(\sqrt n+1\),然后对于每一个\(i\),求出\(i\)的答案\(t\),二分一个与它答案相同的最右边的点,并把这一段的答案更新为\(t\),这样最多二分\(\sqrt n\)次(最多只有\(\sqrt n\)种答案),每次二分(算上check)的复杂度是\(O(n logn)\),所以这部分的复杂度就是\(O(n \sqrt n log n)\),总的复杂度也就是\(O(n \sqrt n log n)\)。

上面把分治的节点默认为\(\sqrt n\)只是为了理解起来直观,事实上复杂度还可以更优。我们发现两块的复杂度还不是很平衡,设分治的节点是\(T\),那么第一块的复杂度就是\(Tn\),第二块就是\(\frac{n^2 log n}{T}\)。要使复杂度最低,就应该取\(T=\sqrt{n log n}\)。这样的程序运行效率(理论结果)大概是取\(T\)为\(\sqrt n\)的两倍。

#include<cstdio>
#include<cctype>
#include<cmath>
#define R register
#define I inline
using namespace std;
const int S=100003,N=200003;
char buf[1000000],*p1,*p2;
I char gc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,S,stdin),p1==p2)?EOF:*p1++;}
I int rd(){
R int f=0; R char c=gc();
while(c<48||c>57) c=gc();
while(c>47&&c<58) f=f*10+(c^48),c=gc();
return f;
}
int h[S],s[N],g[N],p[S],d[S],f[S],o[S],n,c,e;
I int max(int x,int y){return x>y?x:y;}
I void add(int x,int y){s[++c]=h[x],h[x]=c,g[c]=y;}
void dfs(int x,int f){
for(R int i=h[x],y;i;i=s[i])
if((y=g[i])^f)
dfs(y,x);
p[x]=f,d[++e]=x;
}
I int slv(int k){
R int i,x,r=0;
for(i=1;i<=n;++i)
f[i]=1;
for(i=1;i<=n;++i){
x=d[i];
if(p[x]&&(~f[p[x]])&&(~f[x]))
if(f[x]+f[p[x]]>=k)
++r,f[p[x]]=-1;
else
f[p[x]]=max(f[p[x]],f[x]+1);
}
return r;
}
int main(){
R int q,i,j,x,y,t,l,r,m;
n=rd(),q=sqrt(n*log(n)/log(2));
for(i=1;i<n;++i)
x=rd(),y=rd(),add(x,y),add(y,x);
dfs(1,0),o[1]=n;
for(i=2;i<=q;++i)
o[i]=slv(i);
for(i=q+1;i<=n;i=l+1){
l=i,r=n,t=slv(i);
for(;l<r;slv(m)^t?r=m-1:l=m)
m=l+r+1>>1;
for(j=i;j<=l;++j)
o[j]=t;
}
for(i=1;i<=n;++i)
printf("%d\n",o[i]);
return 0;
}

鸣谢:@fwat julao

CF1039D You Are Given a Tree 根号分治,贪心的更多相关文章

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

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

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

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

  3. Codeforces 1039D You Are Given a Tree [根号分治,整体二分,贪心]

    洛谷 Codeforces 根号分治真是妙啊. 思路 考虑对于单独的一个\(k\)如何计算答案. 与"赛道修建"非常相似,但那题要求边,这题要求点,所以更加简单. 在每一个点贪心地 ...

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

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

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

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

  6. 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 xor (根号分治)

    xor There is a tree with nn nodes. For each node, there is an integer value a_ia​i​​, (1 \le a_i \le ...

  7. BZOJ.4320.[ShangHai2006]Homework(根号分治 分块)

    BZOJ \(\mathbb{mod}\)一个数\(y\)的最小值,可以考虑枚举剩余系,也就是枚举区间\([0,y),[y,2y),[2y,3y)...\)中的最小值(求后缀最小值也一样)更新答案,复 ...

  8. [CF1039D]You Are Given a Tree

    [CF1039D]You Are Given a Tree 题目大意: 给定一棵\(n(n\le10^5)\)个节点的树.对于每一个正整数\(k(1\le k\le n)\),求最多能找出多少条包含\ ...

  9. CF1039E Summer Oenothera Exhibition 贪心、根号分治、倍增、ST表

    传送门 感谢这一篇博客的指导(Orzwxh) $PS$:默认数组下标为$1$到$N$ 首先很明显的贪心:每一次都选择尽可能长的区间 不妨设$d_i$表示在取当前$K$的情况下,左端点为$i$的所有满足 ...

随机推荐

  1. Ubuntu安装 和 python开发

    在ubuntu上安装pycharm 可以好几种下载办法 1.pycharm之linux版本下载地址: https://download.jetbrains.8686c.com/python/pycha ...

  2. Flask配置文件和 路由系统

    debug = True开启debug模式 当你的代码在界面增减之后不用刷新界面自动更新 app.logger.error("这是error模式") app.logger.info ...

  3. iOS开发中常用的数学函数

    iOS开发中常用的数学函数 /*---- 常用数学公式 ----*/ //指数运算 3^2 3^3 NSLog(,)); //result 9 NSLog(,)); //result 27 //开平方 ...

  4. 让两个对象间建立weak关系

    让两个对象间建立weak关系 这是为了给两个对象间建立weak关系,当一个对象被释放时,另外一个对象再获取这个值时就是nil,也就是不持有这个对象:) 源码: WeakRelatedDictionar ...

  5. consul日常操作命令

    #开发模式运行agent consul agent -dev #查看consul 集群成员 consul members [-detailed] members命令的输出基于gossip协议,并最终一 ...

  6. PHP CLI模式下echo换行

    近日在执行导库程序的时候,需要在CLI模式下运行程序进行调试,如下图,这是什么鬼?不是我想要的结果 后经过查资料发现代码中执行的输出为 //错误方法实例 echo '其他-683\n'; //正确打开 ...

  7. map filter 的func 放在前面

    map    filter      的func 放在前面 sorted 在后 (    iter..  ,       key=function')

  8. 第一篇,编译生成libcef_dll_wrapper

    因为工作原因需要在程序里面嵌入地图,在网上看了百度地图和高德地图都没有提供c++的接口,提供有web接口,那只好在程序里面嵌入web控件了,第一想到的是web browser控件,接着脑海里又想到IE ...

  9. python第二十课——math模块中常用的函数

    属性: e:自然数 pi:圆周率 函数: ceil():向上取整 floor():向下取整 sqrt():开平方根 radians():角度转弧度 degrees():弧度转角度 import mat ...

  10. 笔记--Yarn

    Yarn,Facebook开源一个新的Javascript包管理工具. 简介 Yarn 是一个新的包管理器,用于替代现有的 npm 客户端或者其他兼容 npm 仓库的包管理工具.Yarn 保留了现有工 ...