原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ407.html

题解

套路啊。

先按照两个节点顺序各搞一个kruskal重构树,然后问题转化成两棵kruskal重构树,不断询问,每次询问让你判断是否有点同时存在于 第一棵树的一个子树 和 第二棵树的一个子树中。

这个东西就转成dfs序之后主席树搞一搞就好了。

代码

  1. #include <bits/stdc++.h>
  2. #include "werewolf.h"
  3. #define clr(x) memset(x,0,sizeof (x))
  4. #define y1 __zzd001
  5. using namespace std;
  6. typedef vector <int> vi;
  7. const int N=400005;
  8. int n,m,q;
  9. vi e[N],ans,tmp;
  10. namespace ufs{
  11. int fa[N];
  12. void init(int n){
  13. for (int i=1;i<=n;i++)
  14. fa[i]=i;
  15. }
  16. int getf(int x){
  17. return fa[x]==x?x:fa[x]=getf(fa[x]);
  18. }
  19. }
  20. struct ktree{
  21. int val[N],son[N][2],fa[N][20];
  22. int I[N],O[N],vis[N];
  23. int cnt,root,Time;
  24. void dfs(int x){
  25. if (!x)
  26. return;
  27. I[x]=++Time;
  28. for (int i=1;i<20;i++)
  29. fa[x][i]=fa[fa[x][i-1]][i-1];
  30. dfs(son[x][0]);
  31. dfs(son[x][1]);
  32. O[x]=Time;
  33. }
  34. void build(vi ord){
  35. clr(val),clr(son),clr(fa),clr(vis);
  36. cnt=n;
  37. ufs::init(n*2);
  38. for (auto x : ord){
  39. val[x]=x,vis[x]=1;
  40. for (auto y : e[x]){
  41. if (!vis[y])
  42. continue;
  43. int fx=ufs::getf(x),fy=ufs::getf(y);
  44. if (fx==fy)
  45. continue;
  46. val[++cnt]=x;
  47. ufs::fa[fx]=ufs::fa[fy]=fa[fx][0]=fa[fy][0]=cnt;
  48. son[cnt][0]=fx,son[cnt][1]=fy;
  49. }
  50. }
  51. for (root=1;fa[root][0];root=fa[root][0]);
  52. Time=0;
  53. dfs(root);
  54. }
  55. }t1,t2;
  56. int c1,c2;
  57. namespace pt{
  58. const int S=N*40;
  59. int val[S],ls[S],rs[S],root[N],cnt,m;
  60. int build(int L,int R){
  61. int rt=++cnt;
  62. if (L==R)
  63. return rt;
  64. int mid=(L+R)>>1;
  65. ls[rt]=build(L,mid);
  66. rs[rt]=build(mid+1,R);
  67. return rt;
  68. }
  69. void init(int _m){
  70. clr(val),clr(ls),clr(rs),clr(root),cnt=0;
  71. root[0]=build(1,m=_m);
  72. }
  73. void update(int prt,int &rt,int L,int R,int x){
  74. if (!rt||rt==prt)
  75. rt=++cnt,val[rt]=val[prt],ls[rt]=ls[prt],rs[rt]=rs[prt];
  76. val[rt]++;
  77. if (L==R)
  78. return;
  79. int mid=(L+R)>>1;
  80. if (x<=mid)
  81. update(ls[prt],ls[rt],L,mid,x);
  82. else
  83. update(rs[prt],rs[rt],mid+1,R,x);
  84. }
  85. int Query(int prt,int rt,int L,int R,int xL,int xR){
  86. if (xR<L||R<xL)
  87. return 0;
  88. if (xL<=L&&R<=xR)
  89. return val[rt]-val[prt];
  90. int mid=(L+R)>>1;
  91. return Query(ls[prt],ls[rt],L,mid,xL,xR)
  92. +Query(rs[prt],rs[rt],mid+1,R,xL,xR);
  93. }
  94. int Query(int x1,int x2,int y1,int y2){
  95. return Query(root[x1-1],root[x2],1,m,y1,y2);
  96. }
  97. }
  98. vi check_validity(int n,vi X,vi Y,vi S,vi E,vi L,vi R){
  99. ::n=n,m=(int)X.size(),q=(int)S.size(),ans.clear();
  100. for (int i=0;i<m;i++)
  101. X[i]++,Y[i]++;
  102. for (int i=0;i<q;i++)
  103. S[i]++,E[i]++,L[i]++,R[i]++;
  104. for (int i=1;i<=n;i++)
  105. e[i].clear();
  106. for (int i=0;i<m;i++){
  107. e[X[i]].push_back(Y[i]);
  108. e[Y[i]].push_back(X[i]);
  109. }
  110. tmp.clear();
  111. for (int i=1;i<=n;i++)
  112. tmp.push_back(i);
  113. t1.build(tmp),t1.val[0]=1e9;
  114. reverse(tmp.begin(),tmp.end());
  115. t2.build(tmp),t2.val[0]=-1e9;
  116. c1=t1.cnt,c2=t2.cnt;
  117. tmp.resize(c1+1);
  118. for (int i=1;i<=c1;i++)
  119. tmp[t1.I[i]]=i;
  120. pt::init(c2);
  121. for (int i=1;i<=c1;i++){
  122. int x=tmp[i];
  123. pt::root[i]=pt::root[i-1];
  124. if (x<=n)
  125. pt::update(pt::root[i-1],pt::root[i],1,pt::m,t2.I[x]);
  126. }
  127. for (int i=0;i<q;i++){
  128. int x=S[i],y=E[i],l=L[i],r=R[i];
  129. if (x<l||y>r){
  130. ans.push_back(0);
  131. continue;
  132. }
  133. for (int i=19;i>=0;i--){
  134. if (t2.val[t2.fa[x][i]]>=l)
  135. x=t2.fa[x][i];
  136. if (t1.val[t1.fa[y][i]]<=r)
  137. y=t1.fa[y][i];
  138. }
  139. int t=pt::Query(t1.I[y],t1.O[y],t2.I[x],t2.O[x]);
  140. ans.push_back(t?1:0);
  141. }
  142. return ans;
  143. }

  

UOJ#407. 【IOI2018】狼人 Kruskal,kruskal重构树,主席树的更多相关文章

  1. luoguP4197:Peaks(Kruskal重构树+主席树)或者(点分树+离线)

    题意:有N座山,M条道路.山有山高,路有困难值(即点权和边权).现在Q次询问,每次给出(v,p),让求从v出发,只能结果边权<=p的边,问能够到达的山中,第K高的高度(从大到小排序). 思路:显 ...

  2. LOJ.2865.[IOI2018]狼人(Kruskal重构树 主席树)

    LOJ 洛谷 这题不就是Peaks(加强版)或者归程么..这算是\(IOI2018\)撞上\(NOI2018\)的题了? \(Kruskal\)重构树(具体是所有点按从小到大/从大到小的顺序,依次加入 ...

  3. [IOI2018] werewolf 狼人 [kruskal重构树+主席树]

    题意: 当你是人形的时候你只能走 \([L,N-1]\) 的编号的点(即大于等于L的点) 当你是狼形的时候你只能走 \([1,R]\) 的编号的点(即小于等于R的点) 然后问题转化成人形和狼形能到的点 ...

  4. Luogu4899 IOI2018狼人(kruskal重构树+主席树)

    可以发现询问的即是“由起点开始‘只经过编号大于等于l的点’所形成的连通块”与“由终点开始‘只经过编号小于等于r的点’所形成的连通块”是否有交集.于是建出重构树,就可以知道每个询问的连通情况了.现在要知 ...

  5. 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1202  Solved: 321[Submit][Sta ...

  6. BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增

    题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...

  7. luogu4197 Peaks (kruskal重构树+主席树)

    按照边权排序建出kruskal重构树,每次就变成了先找一个权值<=x的最远的祖先,然后看这个子树的第k小.离散化一下,在dfs序上做主席树即可 而且只需要建叶节点的主席树 注意输出的是第k小点的 ...

  8. 洛谷P4197 Peaks(Kruskal重构树 主席树)

    题意 题目链接 往后中文题就不翻译了qwq Sol 又是码农题..出题人这是强行把Kruskal重构树和主席树拼一块了啊.. 首先由于给出的限制条件是<=x,因此我们在最小生成树上走一定是最优的 ...

  9. [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)

    3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2438  Solved: 763[Submit][ ...

随机推荐

  1. python中的__metaclass__

    什么是元类: python中类也是一种对象, 可以称为类对象. 元类就是用来创建类对象的"东西". 你创建类就是为了创建类的实例对象, 不是吗? 但是我们已经学习了python中的 ...

  2. 我对SAP Business One 项目实施的理解

    一.什么是SAP: 大家都知道ERP是什么,ERP是企业资源计划管理系统.是指建立在信息技术基础上,集信息技术与先进管理思想于一身,以系统化的管理思想,为企业员工及决策层提供决策手段的管理平台.那么问 ...

  3. G1 垃圾收集器入门

    最近在复习Java GC,因为G1比较新,JDK1.7才正式引入,比较艰难的找到一篇写的很棒的文章,粘过来mark下.总结这篇文章和其他的资料,G1可以基本稳定在0.5s到1s左右的延迟,但是并不能保 ...

  4. Django的admin视图的使用

    要现在admin.py文件中将你要视图化操作的类进行注册: from django.contrib import admin from api import models # Register you ...

  5. 微星X470主板装机

    记录一下装机过程,以作纪念 配置 机箱:先马黑洞3 电源:先马金牌500w CPU:AMD 锐龙5:2600X 主板:微星 X470 暗黑版 显卡:七彩虹 RTX2060 内存:科赋 3200,2条8 ...

  6. MySql实现分页查询的SQL,mysql实现分页查询的sql语句 (转)

    http://blog.csdn.net/sxdtzhaoxinguo/article/details/51481430 摘要:MySQL数据库实现分页查询的SQL语句写法! 一:分页需求: 客户端通 ...

  7. NOI-OJ 2.2 ID:1696 逆波兰表达式

    思路 很容易看出规律,一个运算符出现,其后就一定需要左值和右值,而左值和右值有可能还是运算符,这就需要继续递归.递归终止的条件就是遇到数字. 逆波兰表达式其实是构造成了一颗二叉树 例程 #includ ...

  8. java集合分割

    java集合分割成等份的小集合: private <T> List<List<T>> getSubList(List list,int len) { if(list ...

  9. ES6 Class语法学习

    前言 大多数面向对象的编程语言都支持类和类继承的特性,而JS却不支持这些特性,只能通过其他方法定义并关联多个相似的对象,这种状态一直延续到了ES5.由于类似的库层出不穷,最终还是在ECMAScript ...

  10. 如果在ie上报错又找不到问题原因该怎么办?

    我司项目需要兼容IE浏览器 QQ浏览器 360浏览器,调了几天发现QQ跟360都没问题了然后只剩下一个问题就是IE上报错了!!! 然后去百度找了各种原因  最后发现在IE浏览器这种引入方式无法解析会报 ...