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小就可以。

不过要注意的是,我找出来的那个点深度大于我在做的这个点的深度的话,是不合法的,要判掉。

  1 #include<bits/stdc++.h>
  2 #define pa pair<int,int>
  3 #define ll long long
  4 using namespace std;
  5 const int maxn=200020,logn=22;
  6
  7 ll rd(){
  8     ll x=0;char c=getchar();int neg=1;
  9     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
 10     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
 11     return x*neg;
 12 }
 13
 14 int N,M,L,Q;
 15 int lg[maxn],dep[maxn],fa[maxn][logn];
 16 int egh[maxn],eg[maxn*2][2],ect;
 17 int pth[maxn],pt[maxn*2][2],pct;
 18 int id[maxn],dfn[maxn][2],tot,lst[maxn];
 19 int ch[maxn*logn*8][2],sum[maxn*logn*8],root[maxn*2],rct;
 20
 21 inline void adeg(int a,int b){
 22     eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect;
 23 }
 24 inline void adpt(int a,int d){
 25     pt[++pct][0]=d;pt[pct][1]=pth[a];pth[a]=pct;
 26 }
 27
 28 void dfs(int x){
 29     dfn[x][0]=++tot;id[tot]=x;
 30     for(int i=1;fa[x][i-1]&&fa[fa[x][i-1]][i-1];i++){
 31         fa[x][i]=fa[fa[x][i-1]][i-1];
 32     }
 33     for(int i=egh[x];i!=-1;i=eg[i][1]){
 34         if(dfn[eg[i][0]][0]) continue;
 35         dep[eg[i][0]]=dep[x]+1;fa[eg[i][0]][0]=x;
 36         L=max(L,dep[x]+1);dfs(eg[i][0]);
 37     }dfn[x][1]=tot;
 38 }
 39
 40 inline int lca(int x,int y){
 41     if(dep[x]<dep[y]) swap(x,y);
 42     while(dep[x]>dep[y]){
 43         x=fa[x][lg[dep[x]-dep[y]]];
 44     }if(x==y) return x;
 45     for(int i=lg[dep[x]-1];i>=0;i--){
 46         if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
 47     }return fa[x][0];
 48 }
 49
 50 void add(int &rn,int ro,int l,int r,int x){
 51     rn=++rct;sum[rn]=sum[ro]+1;
 52     if(l<r){int m=l+r>>1;
 53         if(x<=m){
 54             add(ch[rn][0],ch[ro][0],l,m,x);ch[rn][1]=ch[ro][1];
 55         }else{
 56             add(ch[rn][1],ch[ro][1],m+1,r,x);ch[rn][0]=ch[ro][0];
 57         }
 58     }
 59 }
 60 int query(int rn,int ro,int l,int r,int k){
 61     //printf("%d %d %d %d %d %d\n",l,r,rn,ro,sum[rn],sum[ro]);
 62     if(k>sum[rn]-sum[ro]) return -1;
 63     if(l==r) return l;
 64     else{
 65         int m=l+r>>1,w=sum[ch[rn][0]]-sum[ch[ro][0]];
 66         if(w>=k) return query(ch[rn][0],ch[ro][0],l,m,k);
 67         else return query(ch[rn][1],ch[ro][1],m+1,r,k-w);
 68     }
 69 }
 70
 71 inline int solve(int x,int k){
 72     if(!k) return dep[x]-1;
 73     int y=query(root[lst[dfn[x][1]]],root[lst[dfn[x][0]-1]],1,L,k);
 74     if(y==-1||dep[x]<y) return 0;
 75     else return dep[x]-y;
 76 }
 77
 78 int main(){
 79     //freopen("protect.in","r",stdin);
 80     int i,j,k;
 81     N=rd(),M=rd();memset(egh,-1,sizeof(egh));
 82     for(i=1,j=0,k=2;i<=N+10;i++){
 83         if(i>=k) j++,k<<=1;lg[i]=j;
 84     }
 85     for(i=1;i<N;i++){
 86         int a=rd(),b=rd();
 87         adeg(a,b);adeg(b,a);
 88     }dep[1]=1;dfs(1);memset(pth,-1,sizeof(pth));
 89     for(i=1;i<=M;i++){
 90         int a=rd(),b=rd();
 91         int x=lca(a,b);
 92         adpt(a,dep[x]);adpt(b,dep[x]);
 93     }
 94     for(i=1,k=0;i<=N;i++){
 95         for(j=pth[id[i]];j!=-1;j=pt[j][1]){
 96             ++k;add(root[k],root[k-1],1,L,pt[j][0]);
 97         }lst[i]=k;
 98     }
 99     Q=rd();
100     for(i=1;i<=Q;i++){
101         int a=rd(),b=rd();
102         printf("%d\n",solve(a,b));
103     }
104     return 0;
105 }

转载于:https://www.cnblogs.com/Ressed/p/9628631.html

nowcoder172C 保护 (倍增lca+dfs序+主席树)相关推荐

  1. HDU 6203 ping ping ping (在线倍增lca+DFS序+树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6203 #include<bits/stdc++.h> using namespace st ...

  2. codeforces E. Jamie and Tree LCA+dfs序+线段树

    题解: 写起来还稍微有点麻烦. dfs序+线段树可以维护子树的整体修改和查询. 因此,这道题我们要往子树上靠. 我们首先从1号点进行dfs遍历,顺便求出点的dfs序和深度,然后我们采用倍增的思想,可以 ...

  3. 洛谷 - P4197 Peaks(Kruskal重构树+dfs序+主席树)

    题目链接:点击查看 题目大意:有 n 座山峰,每座山峰有他的高度 h[ i ] ,有些山峰之间有双向道路相连,共 m 条路径,每条路径有一个困难值,这个值越大表示越难走. 现在有 q 组询问,每组询问 ...

  4. HDU - 6203 ping ping ping(LCA+dfs序+线段树)

    题目链接:点击查看 题目大意:给出一棵由n+1个节点组成的数,节点编号为0~n(这个无关紧要,预处理时所有节点以及n都自增1即可转换为正常的模型了),现在给出m组节点u和v,问若想让m组u和v都断开连 ...

  5. POJ - 2763 Housewife Wind LCA+dfs序+线段树

    q次询问求两个点之间的距离,并且可以随时修改某条边的长度,最短距离可以用lca来求,但是树上维护每一个点到root的距离必须要用dfs序来记录时间戳,在dfs的时候顺便记录每一条边(u,v)对应的v节 ...

  6. 洛谷 - P3899 [湖南集训]谈笑风生(dfs序+主席树/二维数点)

    题目链接:点击查看 题目大意:设 TTT 为一棵有根树,我们做如下的定义: 设 aaa 和 bbb 为 TTT 中的两个不同节点.如果 aaa 是 bbb 的祖先,那么称"aaa 比 bbb ...

  7. 【BZOJ3439】Kpm的MC密码,trie树+dfs序+主席树

    Time:2016.05.07 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: 1.have a trie,还得是倒着建的,记录每个结尾节点的id(可能会有重复,所以开一个vecto ...

  8. 2021牛客多校7 - xay loves trees(dfs序+主席树-标记永久化)

    题目链接:点击查看 题目大意:给出两棵以点 111 为根节点的有根树,现在要求满足条件的最大集合: 在第一棵树中,集合内的任意两个点都必须满足祖先关系,即 uuu 是 vvv 的祖先或 vvv 是 u ...

  9. 2021牛客暑期多校训练营7 xay loves trees dfs序 + 主席树

    传送门 文章目录 题意: 思路: 题意: 给你两棵树,让你在第一棵树选一条最长的深度递增的链,链上每一个点在第二棵树上都不互为祖先. n≤3e5n\le3e5n≤3e5 思路: 之前做过差不多的题传送 ...

最新文章

  1. android使用webview上传文件,Android项目中如何在webview页面中上传文件
  2. Oracle专家调优秘密
  3. IE工具条不能自动显示
  4. dwz框架中动态添加查找带回组件
  5. Go--4大基本数据类型之布尔类型
  6. apache http server 停止工作_宝塔apache启动失败:报错 AH00526: Syntax error on line 解决方案...
  7. 金蝶kis仓库管理系统演示_金蝶KIS专业版生产管理的系统亮点功能
  8. 今天加入了“宇宙通史:木星”
  9. 机器学习的基本概念和相关术语
  10. ofo 回应甩卖办公桌;华为与袁隆平合作;罗永浩 1 亿股权遭冻结 | 极客头条
  11. python基本内容讲解_Python命名约定基本内容解析
  12. android下载模块封装,AndroidStudio 3.0 NDK开发2-AAR模块封装
  13. javascript数据结构——栈
  14. Python 从零开始制作自己的声音 - wave模块读写wav文件详解
  15. 破解vba工程密码——VBA代码
  16. 【打卡帖】7日玩转ESP32——(第5日) 通过串口的WiFi 配网
  17. 用python操作浏览器的三种方式_经验 | python 操作浏览器的三种方式
  18. webpack 拾翠:充分利用 CommonsChunkPlugin()
  19. js(javascript)和jq(jquery)常见问题(持续更新)
  20. Python: 使用sphinx生成python项目文档

热门文章

  1. centos6.5 rpm安装mysql_CentOS6.5系统下RPM包安装MySQL5.6(转)
  2. 语言逻辑运算符两侧运算对象_5.3 C语言逻辑运算符与表达式
  3. java学习笔记_Java学习笔记day11
  4. thinkphp json_原创干货 | Thinkphp序列化合总
  5. 计算机实现数论 奇偶排列问题
  6. linux查询设备文件信息失败怎么办,Linux下使用blkid命令查询设备及文件系统信息的方法...
  7. python使用欧氏距离knn_python运用sklearn实现KNN分类算法
  8. mysql g月份分组_PowerBI快捷键——视觉对象分组功能
  9. python程序、画一个笑脸_如何使用canvas画一个微笑的表情(代码示例)
  10. PCM设备能在公网使用吗?