博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2019.01.20 bzoj3784: 树上的路径(二分答案+点分治)
阅读量:4973 次
发布时间:2019-06-12

本文共 1289 字,大约阅读时间需要 4 分钟。

点分治好题。
题意简述:给一棵带边权的树,问所有路径中前mmm大的。m≤300000m\le300000m300000


思路:

网上有题解写了可以通过什么点分治序转化成超级钢琴那道题的做法蒟蒻吓得瑟瑟发抖。
然后由于我比较菜想了一个二分答案的方法。
我们二分第mmm大的值,每次用点分治检验合法性。
二分完了之后我们再跑一次点分统计答案。
然后第一个二分的时候直接做是logn3log^3_nlogn3的。
考虑降下来一个logloglog
我们先dfsdfsdfs一次树把每个点作为重心的时候的所有distdistdist预处理下来就可以省掉一个logloglog啦! 空间复杂度O(nlogn)233
代码:

#include
#define ri register int#define fi first#define se secondusing namespace std;inline int read(){
int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar(); return ans;}typedef long long ll;typedef pair
pii;const int N=5e4+5,M=3e5+5;int n,m,siz[N],msiz[N],stk[M],top=0,rt,all,Rt;bool vis[N];vector
e[N];vector
dis[N],g[N],inv[N];ll ans;priority_queue
ANS;void getroot(int p,int fa){
siz[p]=1,msiz[p]=0; for(ri i=0,v;i
&anc){ anc.push_back(dist); for(ri i=0,v;i
&v,int lim){ ll ret=0; for(ri i=0;i
=m)return; for(ri i=0;i
=m*2;}void DFS(int p,int fa,int dist){ stk[++top]=dist; for(ri i=0,v;i
>1; if(check(mid))K=mid,L=mid+1; else R=mid-1; } memset(vis,0,sizeof(vis)),ask(Rt,K); for(ri i=1;i<=m;++i){ if(ANS.size())cout<
<<'\n',ANS.pop(); else cout<
<<'\n'; } return 0;}

转载于:https://www.cnblogs.com/ldxcaicai/p/10367744.html

你可能感兴趣的文章
PHP函数 ------ ctype_alnum
查看>>
网站安全
查看>>
WS-Addressing 初探
查看>>
.NET+模块编排+数据库操作类的封装+分层架构+实体类+Ajax.net+Athem.NET+javascript+Activex组件+用户权限等...
查看>>
Markdown不常见功能
查看>>
(二)NUnit单元测试心得
查看>>
hdu_2604Queuing(快速幂矩阵)
查看>>
frame.bounds和center
查看>>
HDU 1102 Constructing Roads
查看>>
android StaticLayout参数解释
查看>>
多线程之ThreadLocal类
查看>>
Qt-读取文本导出word
查看>>
OC语言description方法和sel
查看>>
C#中得到程序当前工作目录和执行目录的五种方法
查看>>
扫描线与悬线
查看>>
用队列和链表的方式解决约瑟夫问题
查看>>
python 迭代器与生成器
查看>>
基于ASP.NET WEB API实现分布式数据访问中间层(提供对数据库的CRUD)
查看>>
[django实践]投票app
查看>>
[django]form的content-type(mime)
查看>>