nowcoder172C 保护 (倍增lca+dfs序+主席树)
https://www.nowcoder.com/acm/contest/172/C
(sbw大佬太强啦 orz)
先把每一个路径(x,y)分成(x,lca),(y,lca)两个路径,然后就能发现,对于某两个(直上直下的)路径a,b,b的下端点在a的下端点子树中,且b的上端点深度<=a的上端点深度,那么b是覆盖a的。
这样的话,我们做一个dfs序,那么能覆盖某个路径的个数就是(下端点在dfs序对应的那个区间中的、上端点深度小于要覆盖的那个路径)的路径的个数。
而且比较容易发现,我们要求的其实就是dfs序那个区间里的深度第k小的路径。
这样的话,就可以搞一个主席树,以深度为权值,每条路径下端点的dfs序为时间往里加值,每次只要询问对应区间的第k小就可以。
不过要注意的是,我找出来的那个点深度大于我在做的这个点的深度的话,是不合法的,要判掉。
#include<bits/stdc++.h>
#define pa pair<int,int>
#define ll long long
using namespace std;
const int maxn=,logn=; ll rd(){
ll x=;char c=getchar();int neg=;
while(c<''||c>''){if(c=='-') neg=-;c=getchar();}
while(c>=''&&c<='') x=x*+c-'',c=getchar();
return x*neg;
} int N,M,L,Q;
int lg[maxn],dep[maxn],fa[maxn][logn];
int egh[maxn],eg[maxn*][],ect;
int pth[maxn],pt[maxn*][],pct;
int id[maxn],dfn[maxn][],tot,lst[maxn];
int ch[maxn*logn*][],sum[maxn*logn*],root[maxn*],rct; inline void adeg(int a,int b){
eg[++ect][]=b;eg[ect][]=egh[a];egh[a]=ect;
}
inline void adpt(int a,int d){
pt[++pct][]=d;pt[pct][]=pth[a];pth[a]=pct;
} void dfs(int x){
dfn[x][]=++tot;id[tot]=x;
for(int i=;fa[x][i-]&&fa[fa[x][i-]][i-];i++){
fa[x][i]=fa[fa[x][i-]][i-];
}
for(int i=egh[x];i!=-;i=eg[i][]){
if(dfn[eg[i][]][]) continue;
dep[eg[i][]]=dep[x]+;fa[eg[i][]][]=x;
L=max(L,dep[x]+);dfs(eg[i][]);
}dfn[x][]=tot;
} inline int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
while(dep[x]>dep[y]){
x=fa[x][lg[dep[x]-dep[y]]];
}if(x==y) return x;
for(int i=lg[dep[x]-];i>=;i--){
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
}return fa[x][];
} void add(int &rn,int ro,int l,int r,int x){
rn=++rct;sum[rn]=sum[ro]+;
if(l<r){int m=l+r>>;
if(x<=m){
add(ch[rn][],ch[ro][],l,m,x);ch[rn][]=ch[ro][];
}else{
add(ch[rn][],ch[ro][],m+,r,x);ch[rn][]=ch[ro][];
}
}
}
int query(int rn,int ro,int l,int r,int k){
//printf("%d %d %d %d %d %d\n",l,r,rn,ro,sum[rn],sum[ro]);
if(k>sum[rn]-sum[ro]) return -;
if(l==r) return l;
else{
int m=l+r>>,w=sum[ch[rn][]]-sum[ch[ro][]];
if(w>=k) return query(ch[rn][],ch[ro][],l,m,k);
else return query(ch[rn][],ch[ro][],m+,r,k-w);
}
} inline int solve(int x,int k){
if(!k) return dep[x]-;
int y=query(root[lst[dfn[x][]]],root[lst[dfn[x][]-]],,L,k);
if(y==-||dep[x]<y) return ;
else return dep[x]-y;
} int main(){
//freopen("protect.in","r",stdin);
int i,j,k;
N=rd(),M=rd();memset(egh,-,sizeof(egh));
for(i=,j=,k=;i<=N+;i++){
if(i>=k) j++,k<<=;lg[i]=j;
}
for(i=;i<N;i++){
int a=rd(),b=rd();
adeg(a,b);adeg(b,a);
}dep[]=;dfs();memset(pth,-,sizeof(pth));
for(i=;i<=M;i++){
int a=rd(),b=rd();
int x=lca(a,b);
adpt(a,dep[x]);adpt(b,dep[x]);
}
for(i=,k=;i<=N;i++){
for(j=pth[id[i]];j!=-;j=pt[j][]){
++k;add(root[k],root[k-],,L,pt[j][]);
}lst[i]=k;
}
Q=rd();
for(i=;i<=Q;i++){
int a=rd(),b=rd();
printf("%d\n",solve(a,b));
}
return ;
}
nowcoder172C 保护 (倍增lca+dfs序+主席树)的更多相关文章
- 【bzoj3545/bzoj3551】[ONTAK2010]Peaks/加强版 Kruskal+树上倍增+Dfs序+主席树
bzoj3545 题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询 ...
- 【bzoj1146】[CTSC2008]网络管理Network 倍增LCA+dfs序+树状数组+主席树
题目描述 M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工作,公司搭建了一个连接整个公司的通信网络.该网络的结构由N个路由器和N-1条高 ...
- 2018.09.30 bzoj3551:Peaks加强版(dfs序+主席树+倍增+kruskal重构树)
传送门 一道考察比较全面的题. 这道题又用到了熟悉的kruskal+倍增来查找询问区间的方法. 查到询问的子树之后就可以用dfs序+主席树统计答案了. 代码: #include<bits/std ...
- dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448
4448: [Scoi2015]情报传递 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 588 Solved: 308[Submit][Status ...
- 【bzoj1803】Spoj1487 Query on a tree III DFS序+主席树
题目描述 You are given a node-labeled rooted tree with n nodes. Define the query (x, k): Find the node w ...
- [xdoj1216]子树第k小(dfs序+主席树)
解题关键:dfs序将树映射到区间,然后主席树求区间第k小,为模板题. #pragma comment(linker, "/STACK:1024000000,1024000000") ...
- BZOJ 3439: Kpm的MC密码 (trie+dfs序主席树)
题意 略 分析 把串倒过来插进trietrietrie上, 那么一个串的kpmkpmkpm串就是这个串在trietrietrie上对应的结点的子树下面的所有字符串. 那么像 BZOJ 3551/354 ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增
建出来 $Kruskal$ 重构树. 将询问点向上跳到深度最小,且合法的节点上. 那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达. 对于子树中求点权第 $k$ 大的问 ...
- 【BZOJ3772】精神污染 DFS序+主席树
[BZOJ3772]精神污染 Description 兵库县位于日本列岛的中央位置,北临日本海,南面濑户内海直通太平洋,中央部位是森林和山地,与拥有关西机场的大阪府比邻而居,是关西地区面积最大的县,是 ...
随机推荐
- core_cm4_simd.h文件是干嘛的?
core_cm4_simd.h文件用于simd指令,即单指令多数据流,这个只有ARMv7架构才有,Cortex m3 m4 m7是ARMv7架构,而Cortex m0 m1是没有的. 所以,在新建Co ...
- Part 5:Django测试--Django从入门到精通系列教程
该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. 本节将简要介绍Django的自动化测试相关内 ...
- VS2017登陆不了,TFS无法连接成功的问题
由于使用的win7 64位操作系统,重装系统以后,安装了vs2017,登陆不成功,https://auth.gfx.ms/16.000.27887.2/OldConvergedLogin_PCore. ...
- 免费的 Vue.js 入门与进阶视频教程
这是我免费发布的高质量超清「Vue.js 入门与进阶视频教程」. 全网最好的.免费的 Vue.js 视频教程,课程基于 Vue.js 2.0,由浅入深,最后结合实际的项目进行了最棒的技术点讲解,此课程 ...
- SpringBoot笔记
官网: http://springboot.fun/ 收集到一个比较全的: https://blog.csdn.net/xiaoyu411502/article/details/52474037 Id ...
- centos7下安装php+memcached简单记录
1)centos7下安装php 需要再添加一个yum源来安装php-fpm,可以使用webtatic(这个yum源对国内网络来说恐怕有些慢,当然你也可以选择其它的yum源) [root@nextclo ...
- Linux下rsyslog日志收集服务环境部署记录
rsyslog 可以理解为多线程增强版的syslog. 在syslog的基础上扩展了很多其他功能,如数据库支持(MySQL.PostgreSQL.Oracle等).日志内容筛选.定义日志格式模板等.目 ...
- Python学习笔记 --第二章
Python语法基础 "#"号为注释符,建议缩进四个空格,Python大小写敏感. 数据类型 整数 0,2等等,以0x开头的为十六进制数 浮点数 1.58e9 字符串 用'或"括起来的任意文 ...
- 5.2&5.3
队友吕日荣 http://www.cnblogs.com/Russelling/ 最近队友有点忙,尽管如此,队友还是有很给力的付出,让我们在最后完成了任务. 一开始都不知道这次的任务是要做什么,毫无头 ...
- (Alpha)Let's-版本发布说明
我们的Let’s APP发布了! (下载地址在“下载与安装”部分) Alpha版本功能 Alpha版本是我们发布的第一个版本,所以仅实现了活动实体和用户实体之间的基础联系功能. 基本功能 登录和注册 ...