【BZOJ4317】Atm的树 动态树分治+二分+线段树
【BZOJ4317】Atm的树
Description
Input
Output
Sample Input
1 5 2
1 2 4
2 3 6
2 4 5
Sample Output
5
10
9
6
HINT
题解:依旧是动态点分治。
统计第k大不太好搞,我们对于每个点都二分一下,变成求到一个点距离<=mid的点有多少个,然后就变成熟悉的题了。
我们对于每个点维护一棵线段树,记录它在点分树的子树中有多少个点到它的距离为x,同时为了去重,还要维护一个从它父亲中减去的版本。
时间复杂度$O(nlog_n^3)$。
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- using namespace std;
- const int maxn=15010;
- int n,m,N,tot,cnt,rt,mn;
- int to[maxn<<1],next[maxn<<1],head[maxn],val[maxn<<1],siz[maxn],fa[maxn],md[20][maxn<<1],pos[maxn],vis[maxn];
- int Log[maxn<<1],dep[maxn],r1[maxn],r2[maxn];
- struct sag
- {
- int ls,rs,siz;
- }s[maxn*100];
- inline int rd()
- {
- int ret=0,f=1; char gc=getchar();
- while(gc<'0'||gc>'9') {if(gc=='-') f=-f; gc=getchar();}
- while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
- return ret*f;
- }
- inline void add(int a,int b,int c)
- {
- to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
- }
- void getrt(int x,int fa)
- {
- int tmp=0,i;
- siz[x]=1;
- for(i=head[x];i!=-1;i=next[i]) if(!vis[to[i]]&&to[i]!=fa)
- getrt(to[i],x),tmp=max(tmp,siz[to[i]]),siz[x]+=siz[to[i]];
- tmp=max(tmp,tot-siz[x]);
- if(tmp<mn) mn=tmp,rt=x;
- }
- void dfs(int x)
- {
- pos[x]=++pos[0],md[0][pos[0]]=dep[x];
- for(int i=head[x];i!=-1;i=next[i]) if(!dep[to[i]]) dep[to[i]]=dep[x]+val[i],dfs(to[i]),md[0][++pos[0]]=dep[x];
- }
- void solve(int x)
- {
- vis[x]=1;
- for(int i=head[x];i!=-1;i=next[i]) if(!vis[to[i]])
- tot=siz[to[i]],mn=1<<30,getrt(to[i],x),fa[rt]=x,solve(rt);
- }
- inline int dis(int x,int y)
- {
- int a=pos[x],b=pos[y];
- if(a>b) swap(a,b);
- int k=Log[b-a+1];
- return dep[x]+dep[y]-2*min(md[k][a],md[k][b-(1<<k)+1]);
- }
- void insert(int l,int r,int &x,int a)
- {
- if(!x) x=++tot;
- s[x].siz++;
- if(l==r) return ;
- int mid=(l+r)>>1;
- if(a<=mid) insert(l,mid,s[x].ls,a);
- else insert(mid+1,r,s[x].rs,a);
- }
- int query(int l,int r,int x,int a,int b)
- {
- if(a>b) return 0;
- if(!x||(a<=l&&r<=b)) return s[x].siz;
- int mid=(l+r)>>1;
- if(b<=mid) return query(l,mid,s[x].ls,a,b);
- if(a>mid) return query(mid+1,r,s[x].rs,a,b);
- return query(l,mid,s[x].ls,a,b)+query(mid+1,r,s[x].rs,a,b);
- }
- inline int calc(int x,int mid)
- {
- int ret=0,y,z;
- for(y=x;y;y=z)
- {
- z=fa[y];
- if(z) ret-=query(0,N,r2[y],0,mid-dis(x,z));
- ret+=query(0,N,r1[y],0,mid-dis(x,y));
- }
- return ret;
- }
- int main()
- {
- n=rd(),m=rd()+1;
- int i,j,u,v,a,b,c,l,r,mid;
- memset(head,-1,sizeof(head));
- for(i=1;i<n;i++) a=rd(),b=rd(),c=rd(),add(a,b,c),add(b,a,c),N+=c;
- dep[1]=1,dfs(1),tot=n,mn=1<<30,getrt(1,0),solve(rt);
- for(i=2;i<(n<<1);i++) Log[i]=Log[i>>1]+1;
- for(j=1;(1<<j)<(n<<1);j++) for(i=1;i+(1<<j)-1<(n<<1);i++) md[j][i]=min(md[j-1][i],md[j-1][i+(1<<(j-1))]);
- for(i=1;i<=n;i++)
- {
- for(u=i;u;u=v)
- {
- v=fa[u];
- if(v) insert(0,N,r2[u],dis(i,v));
- insert(0,N,r1[u],dis(i,u));
- }
- }
- for(i=1;i<=n;i++)
- {
- l=0,r=N+1;
- while(l<r)
- {
- mid=(l+r)>>1;
- if(calc(i,mid)>=m) r=mid;
- else l=mid+1;
- }
- printf("%d\n",r);
- }
- return 0;
- }
【BZOJ4317】Atm的树 动态树分治+二分+线段树的更多相关文章
- luoguU60884 【模板】动态点分治套线段树
题目连接:https://www.luogu.org/problemnew/show/U60884 题意:有N个点,标号为1∼N,用N−1条双向带权通道连接,保证任意两个点能互相到达. Q次询问,问从 ...
- BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector
题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...
- 【WC2018】即时战略(动态点分治,替罪羊树)
[WC2018]即时战略(动态点分治,替罪羊树) 题面 UOJ 题解 其实这题我也不知道应该怎么确定他到底用了啥.只是想法很类似就写上了QwQ. 首先链的部分都告诉你要特殊处理那就没有办法只能特殊处理 ...
- 【BZOJ3295】动态逆序对(线段树,树状数组)
[BZOJ3295]动态逆序对(线段树,树状数组) 题面 Description 对于序列A,它的逆序对数定义为满足iAj的数对(i,j)的个数.给1到n的一个排列,按照某种顺序依次删除m个元素,你的 ...
- 【BZOJ2001】[HNOI2010]城市建设(CDQ分治,线段树分治)
[BZOJ2001][HNOI2010]城市建设(CDQ分治,线段树分治) 题面 BZOJ 洛谷 题解 好神仙啊这题.原来想做一直不会做(然而YCB神仙早就切了),今天来怒写一发. 很明显这个玩意换种 ...
- 指针-动态开点&合并线段树
一个知识点不在一道题里说是没有灵魂的 线段树是用来处理区间信息的咯 但是往往因为需要4倍空间让许多人退却,而动态开点的线段树就非常棒 仿佛只用2倍就可以咯 指针保存位置,即节点信息,是很舒适的,所以用 ...
- HDU4614 Vases and Flowers 二分+线段树
分析:感觉一看就是二分+线段树,没啥好想的,唯一注意,当开始摆花时,注意和最多能放的比大小 #include<iostream> #include<cmath> #includ ...
- BZOJ4860 BJOI2017 树的难题 点分治、线段树合并
传送门 只会线段树……关于单调队列的解法可以去看“重建计划”一题. 看到路径长度$\in [L,R]$考虑点分治.可以知道,在当前分治中心向其他点的路径中,始边(也就是分治中心到对应子树的根的那一条边 ...
- J - Joseph and Tests Gym - 102020J (二分+线段树)
题目链接:https://cn.vjudge.net/contest/283920#problem/J 题目大意:首先给你n个门的高度,然后q次询问,每一次询问包括两种操作,第一种操作是将当前的门的高 ...
随机推荐
- 让网页自动调用双核浏览器的极速模式(<meta name="renderer" content="webkit">)
背景:最近做了一个网站,传单服务器之后,每次打开都是乱码,不对啊,我在本地测得明明是排版很整齐啊,然后发现,360用的是“兼容模式”打开的,这就尴尬了,用户一打开就是乱码,这用户体验得有多差!用户可不 ...
- 巧用FTP命令进行文件传输
巧用FTP进行文件传输 Internet作为现代信息高速公路已深入我们的生活,其中它所提供的电子邮件Web网站信息服务已被越来越多的人所熟知和使用.FTP作为Internet的功能之一,虽然没有像 ...
- 已知的问题:本文总结了与Telerik UI for ASP.NET Core相关的所有已知问题。
ASP.NET Core Framework 不支持数据表. 有关此限制的更多信息,请参阅dotnet / corefx#1039. 不支持本地化资源. 有关此限制的更多信息,请参阅dotnet / ...
- centos7防火墙的关闭
从centos7开始使用systemctl来管理服务和程序,包括了service和chkconfig. #systemctl list-unit-files|grep firewalld.servic ...
- 通过Socket连接一次传输多个文件
近期在做一个通过WIFI在手机之间传输文件的功能.须要在手机之间建立一个持久的Socket 连接并利用该连接数据传输.能够一次传输一个或多个文件. 在一次传输多个文件时,遇到了一个困难:怎样在接收文件 ...
- 论Top与ROW_NUMBER读取第一页的效率问题及拼接sql查询条件
http://www.cnblogs.com/Leo_wl/p/4921799.html SELECT TOP * FROM users WHERE nID> And nID< ORDER ...
- Atitit.有分区情况下的表查询策略流程
Atitit.有分区情况下的表查询策略流程 1. 分区表查询策略流程1 2. 常见数据库oracle mysql的分区查询语句1 2.1. 跨分区查询(oracle)1 2.2. 单分区查询 (ora ...
- 27. Retrofit2 -- How to Use Dynamic Urls for Requests
27. Retrofit2 -- How to Use Dynamic Urls for Requests Retrofit tutorial 用户案例场景 如何使用动态 Url 相对于基本地址,动态 ...
- 记centos 安装 mysql5.7.23.tar.gz教程
1.下载tar包,这里使用wget从官网下载 wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.22-linux-glibc2. ...
- android跨进程通信(IPC)——AIDL
转载请标明出处: http://blog.csdn.net/sinat_15877283/article/details/51026711: 本文出自: [温利东的博客] 近期在看 @任玉刚 大神编写 ...