Codeforces Round #507 (Div. 1) D. You Are Given a Tree 根号分治 + dp
传送门
题意:
有一颗nnn个节点的树,其中一个简单路径集合被称为kkk合法当且仅当:
树的每个节点至多属于一条路径,且每条路径恰好包含kkk个点。
对于k∈[1,n]k\in [1,n]k∈[1,n],求kkk合法路径集合最多路径个数,即设kkk合法路径集合为SSS,求最大的∣S∣|S|∣S∣。
2≤n≤1e52\le n\le 1e52≤n≤1e5
思路:
考虑每次用dpdpdp来O(n)O(n)O(n)来求,记一个最大值和次大值,让后就是比较常规的dpdpdp了,这样的复杂度是O(n2)O(n^2)O(n2)的。
考虑到当k∈[n,n]k\in [\sqrt n,n]k∈[n,n]的时候,答案不会超过n\sqrt nn个,也就是每个答案有可能很长一段连续的都是这个答案,且答案递减,所以这个东西有二分的性质。
考虑根号分治,对于k∈[1,n]k\in [1,\sqrt n]k∈[1,n]的情况,我们直接暴力求,复杂度O(nn)O(n\sqrt n)O(nn)。对于k∈[n,n]k\in [\sqrt n,n]k∈[n,n],我们每次二分答案所属区间,复杂度O(nnlogn)O(n\sqrt n logn)O(nnlogn)。
直接写会ttt掉,毕竟这个复杂度还是很高的,所以考虑将dpdpdp的dfsdfsdfs拿出来dfsdfsdfs序,循环跑一下,这样会快很多,可以通过。
// Problem: D. You Are Given a Tree
// Contest: Codeforces - Codeforces Round #507 (Div. 1, based on Olympiad of Metropolises)
// URL: https://codeforces.com/problemset/problem/1039/D
// Memory Limit: 512 MB
// Time Limit: 7000 ms
//
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=100010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n;
int ans[N],block;
vector<int>v[N];
int dfn[N],tot,fa[N],id[N];void dfs(int u,int f) {int mx1=0,mx2=0;int now=0;fa[u]=f;dfn[u]=++tot;for(auto x:v[u]) {if(x==f) continue;dfs(x,u);// now+=y;// if(mx1<len[x]) mx2=mx1,mx1=len[x];// else if(mx2<len[x]) mx2=len[x];}// if(mx1+mx2+1>=k) now++,len[u]=0;// else len[u]=mx1+1;// return now;
}int f[N],mx1[N],mx2[N];
int len[N];int solve(int k) {if(ans[k]!=-1) return ans[k];for(int i=0;i<=n;i++) {mx1[i]=mx2[i]=0;f[i]=0;len[i]=0;}for(int i=1;i<=n;i++) {int now=id[i];int to=fa[now];if(mx1[now]+mx2[now]+1>=k) {f[now]++; len[now]=0;} else len[now]=mx1[now]+1;f[to]+=f[now];if(mx1[to]<len[now]) {mx2[to]=mx1[to];mx1[to]=len[now];} else if(mx2[to]<len[now]) {mx2[to]=len[now];}}return ans[0]=f[0];
}bool cmp(int a,int b) {return dfn[a]>dfn[b];
} int main()
{// ios::sync_with_stdio(false);
// cin.tie(0);memset(ans,-1,sizeof(ans));scanf("%d",&n); block=sqrt(n*log(n)/log(2));for(int i=1;i<=n-1;i++) {int a,b; scanf("%d%d",&a,&b);v[a].pb(b); v[b].pb(a);}dfs(1,0);for(int i=1;i<=n;i++) ans[i]=-1,id[i]=i;sort(id+1,id+1+n,cmp);for(int i=1;i<=block;i++) {ans[i]=solve(i);}int pre=block+1;for(int _=1;pre<=n;_++) {int l=pre,r=n,ne,val;val=solve(l);while(l<=r) {int mid=(l+r)>>1;if(solve(mid)<val) r=mid-1;else l=mid+1,ne=mid;}for(int i=pre;i<=ne;i++) ans[i]=solve(pre);pre=ne+1; }for(int i=1;i<=n;i++) printf("%d\n",ans[i]);return 0;
}
/**/
Codeforces Round #507 (Div. 1) D. You Are Given a Tree 根号分治 + dp相关推荐
- 【Codeforces Round #507 (Div. 2, based on Olympiad of Metropolises) A】Palindrome Dance
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] i从1..n/2循环一波. 保证a[i]和a[n-i+1]就好. 如果都是2的话填上min(a,b)*2就好 其他情况跟随非2的. ...
- 【Codeforces Round #507 (Div. 2, based on Olympiad of Metropolises) B】Shashlik Cooking
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 翻转一次最多影响2k+1个地方. 如果n<=k+1 那么放在1的位置就ok.因为能覆盖1..k+1 如果n<=2k+1 ...
- Codeforces Round #343 (Div. 2) D. Babaei and Birthday Cake 线段树维护dp
D. Babaei and Birthday Cake 题目连接: http://www.codeforces.com/contest/629/problem/D Description As you ...
- Codeforces Round #536 (Div. 2) E. Lunar New Year and Red Envelopes(DP+muitiset优化)
题目链接:http://codeforces.com/contest/1106/problem/E #include<bits/stdc++.h> using namespace std; ...
- szu cf集训Codeforces Round #631 (Div. 2)A ~ D[贪心,数据结构,思维,dp]
A. Dreamoon and Ranking Collection 题意:题意不太好理解.简单来讲就是,给出一组数,能从1最多数到几,不够的用数来填,最多填x次.思路:代码很简单-先出现过的地方肯定 ...
- Codeforces Round #374 (Div. 2) A , B , C 水,水,拓扑dp
A. One-dimensional Japanese Crossword time limit per test 1 second memory limit per test 256 megabyt ...
- Codeforces Round #202 (Div. 1): D. Turtles(Lindström–Gessel–Viennot lemma定理+DP)
题意: 给你一个n*m的地图,"#"是障碍,"."是路,不能走出边界,问从(1,1)到(n,m)选出两条不相交最短路径的方案数是多少(其中起点和终点相同不算相交 ...
- Codeforces Round #614 (Div. 1) C.Xenon's Attack on the Gangs(树形dp)
题目 给你一棵n(n<=3000)个点的树,树上每个点对(u,v)对答案的贡献是mex(u,v), mex就是sg函数里的那个mex 每个点对只被统计一次,令所有点对的贡献和最大,输出贡献和 思 ...
- Codeforces Round #506 (Div. 3)
Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...
最新文章
- Paddle内置的网络模型
- Shareplex 错误 can't open or read object cache file
- 怎么看调用的接口_SpringCloud服务间调用
- javaweb实训第三天下午——Web基础-Servlet交互JSP原理及运用
- micropython和python区别-什么是MicroPython?
- 学习Java,真的可以月薪过万嘛?真实个人经历告诉你,记录了平时学习的内容以及学习过程中最真实的感受(一)
- 计蒜客 第一场 搜狗输入法
- JSP与Servlet 程序设计教程
- 华为光猫查看LOID密码
- maven(2)——修改maven的setting.xml文件,更改下载地址和镜像
- 快手短视频广告投放是怎么收费的 快手信息流广告收费标准
- JS编写 简易网页音乐播放器
- 无盘系统服务器虚拟内存,Windows7无盘虚拟内存如何设置
- ADS(Advanced Design system)良率分析(Yield)、良率优化(YieldOptim)
- iOS微信发布8.0.29版本,苹果14用户快来
- 打谱CTF recover
- 门禁系统远程无线联网解决方案
- 一个北漂程序员的租房经历,黑中介无底线的坑,今晚要流落街头了,在线求解决方法!
- 基于SSM的小区缴费系统
- 多线程之 ForkJoinool线程池(二十四)
热门文章
- 计算机导论上机模拟,计算机导论模拟考试题6份完整版.doc
- 是的,我打败了一个奥特曼。
- 15岁大学毕业,一生800多篇专著论文,双眼失明却凭一条公式称霸数学界
- 51单片机外部地址c语言,cx51与c语言对单片机内部和外部资源变量和地址的定义是否兼容?为什么...
- 计算机视觉领域还有那些坑,深度学习/计算机视觉常见的8个错误总结及避坑指南...
- java 堆栈_Java中线程与堆栈的关系
- 7-1 输出全排列 (20 分)(全排列+递归+图解)Come Baby
- 每天一小时python官方文档学习(三)————函数
- linux 从不兼容的指针类型,警告:从不兼容的指针类型初始化
- js变量和java变量相等,js中变量和jsp中java代码中变量互相访问解决方案