题目描述

在Bytemountains有N座山峰,每座山峰有他的高度\(h_i\)。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

输入输出格式

输入格式:

第一行三个数N,M,Q。 第二行N个数,第ii个数为\(h_i\) 接下来MM行,每行33个数a,b,c,表示从a到b有一条困难值为c的双向路径。 接下来Q行,每行三个数v,x,k,表示一组询问。

输出格式:

对于每组询问,输出一个整数表示答案。

输入输出样例

输入样例#1: 复制

10 11 4

1 2 3 4 5 6 7 8 9 10

1 4 4

2 5 3

9 8 2

7 8 10

7 1 4

6 7 1

6 4 8

2 1 5

10 8 10

3 4 7

3 4 6

1 5 2

1 5 6

1 5 8

8 9 2

输出样例#1: 复制

6

1

-1

8

说明

数据范围

\(N \le 10^5, 0 \le M,Q \le 5\times 10^5,h_i,c,x \le 10^9\)。


kruskal重构树

对于每一个节点其子树的叶子就是在这个点的权值内能相互到达的点

按照dfs序建可持久化权值线段树,dfs序\(u\)到\(u+size[u]\)内每个点的增量就是\(pre[u]\)子树的点

每次查询时把\(v\)倍增跳到\(\leq x\)的最大值,在\((dfn[x]+size[x])-(dfn[x]-1)\)的线段树内找第\(k\)大节点即可


恩......


  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #define M (200005*10)
  6. #define N 200005
  7. #define LL long long
  8. #define max(a,b) ((a)>(b)? (a):(b))
  9. #define min(a,b) ((a)<(b)? (a):(b))
  10. using namespace std;
  11. int top[N],d[M],h[N],ls[M],rs[M],n,m,q,cnt,f[N],edge[N],cnt1,y;
  12. int head[N],ver[N],nex[N],dfn[N],df,pre[M],g,z[N],pp[N],v,x,k,bz[N][26],s[N],az[N][26];
  13. struct vv{ int f,t,edge;} a[M];
  14. inline bool cmp(vv a,vv b) {return a.edge<b.edge;}
  15. inline char gc()
  16. {
  17. static char now[1<<22],*S,*T;
  18. if (T==S)
  19. {
  20. T=(S=now)+fread(now,1,1<<22,stdin);
  21. if (T==S) return EOF;
  22. }
  23. return *S++;
  24. }
  25. inline int gtt()
  26. {
  27. register int x=0,f=1;
  28. register char ch=gc();
  29. while(!isdigit(ch))
  30. {
  31. if (ch=='-') f=-1;
  32. ch=gc();
  33. }
  34. while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=gc();
  35. return x*f;
  36. }
  37. inline void add(int x,int y)
  38. {
  39. cnt1+=1;
  40. ver[cnt1]=y; nex[cnt1]=head[x]; head[x]=cnt1;
  41. }
  42. int ff(int x)
  43. {
  44. if(f[x]==x) return x;
  45. f[x]=ff(f[x]);
  46. return f[x];
  47. }
  48. inline void kru()
  49. {
  50. for(int i=1;i<=m;i++)
  51. {
  52. int w=ff(a[i].f), e=ff(a[i].t);
  53. if(w!=e)
  54. {
  55. f[w]=f[e]=++n;
  56. add(n,w); add(n,e);
  57. edge[n]=a[i].edge;
  58. }
  59. }
  60. }
  61. void dfs(int now)
  62. {
  63. bz[now][0]=edge[now];
  64. s[now]=1; dfn[now]=++df; pre[df]=now;
  65. for(int i=head[now];i;i=nex[i])
  66. {
  67. int t=ver[i];
  68. dfs(t);
  69. bz[t][1]=edge[now];
  70. az[t][1]=now;
  71. s[now]+=s[t];
  72. }
  73. }
  74. void built(int now,int l,int r,int pre,int z)
  75. {
  76. if(l==r)
  77. {
  78. d[now]=d[pre]+1;
  79. return;
  80. }
  81. int mid=(l+r)>>1; ls[now]=ls[pre]; rs[now]=rs[pre];
  82. if(z<=mid)
  83. {
  84. ls[now]=++cnt;
  85. built(ls[now],l,mid,ls[pre],z);
  86. }
  87. if(z>mid)
  88. {
  89. rs[now]=++cnt;
  90. built(rs[now], mid+1, r, rs[pre], z);
  91. }
  92. d[now]=d[ls[now]]+d[rs[now]];
  93. }
  94. void built1(int now,int l,int r)
  95. {
  96. if(l==r) return;
  97. ls[now]=++cnt; rs[now]=++cnt;
  98. int mid=(l+r)>>1;
  99. built1(ls[now], l, mid);
  100. built1(rs[now], mid+1, r);
  101. }
  102. int find(int now1,int now2,int l,int r,int z)
  103. {
  104. if(l==r) return l;
  105. if(d[now2]-d[now1]<z) return -1;
  106. int mid=(l+r)>>1;
  107. if(d[rs[now2]]-d[rs[now1]]>=z) return find(rs[now1], rs[now2], mid+1, r, z);
  108. return find(ls[now1], ls[now2], l, mid, z-d[rs[now2]]+d[rs[now1]]);
  109. }
  110. int main()
  111. {
  112. n=gtt(); m=gtt(); q=gtt(); g=n;
  113. for(int i=1;i<=4*n;i++) f[i]=i;
  114. for(int i=1;i<=n;i++) h[i]=gtt(), z[i]=h[i];
  115. sort(z+1,z+1+n);
  116. int mm=unique(z+1,z+1+n)-z-1;
  117. for(int i=1;i<=n;i++)
  118. {
  119. k=lower_bound(z+1,z+1+mm,h[i])-z;
  120. pp[k]=h[i]; h[i]=k;
  121. }
  122. for(int i=1;i<=m;i++){ a[i].f=gtt(); a[i].t=gtt(); a[i].edge=gtt();}
  123. sort(a+1,a+1+m,cmp); kru();
  124. for(int i=n;i;i--) if(!dfn[i]) dfs(i);
  125. if(g!=1){top[1]=1; cnt=1; built1(1,1,mm);}
  126. else {top[1]=1; cnt=1;built(cnt,1,mm,0,h[pre[1]]);}
  127. for(int i=2;i<=n;i++)
  128. if(pre[i]<=g)
  129. {
  130. top[i]=++cnt;
  131. built(cnt,1,mm,top[i-1],h[pre[i]]);
  132. }
  133. else top[i]=top[i-1];
  134. for(int i=2;i<=25;i++)
  135. for(int j=1;j<=n;j++)
  136. bz[j][i]=bz[az[j][i-1]][i-1], az[j][i]=az[az[j][i-1]][i-1];
  137. for(int i=1;i<=q;i++)
  138. {
  139. v=gtt(); x=gtt(); k=gtt();
  140. for(int j=25;j>=1;j--) if(bz[v][j]<=x && az[v][j]) v=az[v][j];
  141. k=find(top[dfn[v]-1],top[dfn[v]+s[v]-1],1,mm,k);
  142. if(k!=-1)printf("%d\n",pp[k]);
  143. else printf("-1\n");
  144. }
  145. }

P4197 Peaks的更多相关文章

  1. BZOJ 3545 / 洛谷 P4197 Peaks 解题报告

    P4197 Peaks 题目描述 在\(\text{Bytemountains}\)有\(N\)座山峰,每座山峰有他的高度\(h_i\).有些山峰之间有双向道路相连,共\(M\)条路径,每条路径有一个 ...

  2. [luogu P4197] Peaks 解题报告(在线:kruskal重构树+主席树 离线:主席树+线段树合并)

    题目链接: https://www.luogu.org/problemnew/show/P4197 题目: 在Bytemountains有N座山峰,每座山峰有他的高度$h_i$.有些山峰之间有双向道路 ...

  3. Luogu P4197 Peaks

    题目链接 \(Click\) \(Here\) 做法:\(Kruskal\)重构树上跑主席树 构造方法:把每条边拆出来成一个点,点权是原先的边权.每次连边的时候,连的不再是点,而是其原先点所在的联通块 ...

  4. 洛谷P4197 Peaks&&克鲁斯卡尔重构树学习笔记(克鲁斯卡尔重构树+主席树)

    传送门 据说离线做法是主席树上树+启发式合并(然而我并不会) 据说bzoj上有强制在线版本只能用克鲁斯卡尔重构树,那就好好讲一下好了 这里先感谢LadyLex大佬的博客->这里 克鲁斯卡尔重构树 ...

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

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

  6. P4197 Peaks [克鲁斯卡尔重构树 + 主席树][克鲁斯卡尔重构树学习笔记]

    Problem 在\(Bytemountains\)有\(n\)座山峰,每座山峰有他的高度\(h_i\) .有些山峰之间有双向道路相连,共\(M\)条路径,每条路径有一个困难值,这个值越大表示越难走, ...

  7. 洛谷P4197 Peaks (Kruskal重构树)

    读题,只经过困难值小于等于x的路径,容易想到用Kruskal重构树:又要查询第k高的山峰,我们选择用主席树求解. 先做一棵重构树,跑一遍dfs,重构树中每一个非叶子节点对应一段区间,我们开range[ ...

  8. Luogu_4197 Peaks

    P4197 Peaks 并不会克鲁斯卡尔重构树,于是就写了离线算法. 使用了最小生成树,启发式合并treap 在最小生成树,克鲁斯卡尔算法 时 ,将询问一块处理.便可以保证询问时边的要求.然后利用平衡 ...

  9. kruscal重构树略解

    我们先看一道题:Luogu P4197 Peaks 这道题珂以用启发式合并+主席树来做 那么强制在线呢?(bzoj 3551 [ONTAK2010]Peaks加强版) 离线做法就不行了 我们就要用一个 ...

随机推荐

  1. oracle序列的创建和使用

    oracle 序列的创建与使用 (2012-03-15 16:14:09) -------------------------------------------------------------- ...

  2. java性能监控工具jstat

    jstat Monitors Java Virtual Machine (JVM) statistics. This command is experimental and unsupported. ...

  3. OracleServer总结进阶之系统分析(进阶完结)

    个人原创,转载请在文章头部明显位置注明出处:https://www.cnblogs.com/sunshine5683/p/10080102.html 在上一篇进阶中大概讲解了一些关于进阶方面的知识,今 ...

  4. Invoke 和 BeginInvoke 的区别

    在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate 一.为什么Control类提供了Invoke和BeginInvoke机制? 关于这个问题的最主要的原因已经是dot ...

  5. JavaWeb学习总结(十):Session简单使用

    一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...

  6. Python的正则表达式与JSON

    Python的正则表达式需要导入re模块 菜鸟教程:http://www.runoob.com/python/python-reg-expressions.html 官方文档:https://docs ...

  7. mysql 日期时间类型

    datetime timestamp year date time drop table test;create table test (dt datetime, ts timestamp, y ye ...

  8. Phoenix介绍(持续更新)

    现有hbase的查询工具有很多如:Hive,Tez,Impala,Shark/Spark,Phoenix等.今天主要记录Phoenix. phoenix,中文译为“凤凰”,很美的名字.Phoenix是 ...

  9. git pull文件时和本地文件冲突的问题

    在使用git pull代码时,经常会碰到有冲突的情况,提示如下信息: error: Your local changes to 'c/environ.c' would be overwritten b ...

  10. 12.Spring——Web MVC框架

    1.Spring Web MVC 框架 2.Spring MVC Hello World 例子 1.Spring Web MVC 框架 Spring web         MVC 框架提供了模型-视 ...