【BZOJ3551】Peaks加强版(Kruskal重构树,主席树)
【BZOJ3551】Peaks加强版(Kruskal重构树,主席树)
题面
Description
在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。
Input
第一行三个数N,M,Q。
第二行N个数,第i个数为h_i
接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
接下来Q行,每行三个数v x k,表示一组询问。
Output
对于每组询问,输出一个整数表示答案。
Sample Input
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
Sample Output
6
1
-1
8
HINT
【数据范围】
N<=10^5, M,Q<=5*105,h_i,c,x<=109。
题解
很明显的克鲁斯卡尔重构树之后直接用主席树维护区间第\(K\)大。
注意克鲁斯卡尔重构树维护的最小生成树的边权是放在点上的。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 200500
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next;}e[MAX];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
struct edge{int u,v,w;}E[MAX<<2];
bool operator<(edge a,edge b){return a.w<b.w;}
int f[MAX],tot;
int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
int n,m,Q,a[MAX];
int p[20][MAX],dis[MAX];
int dfn[MAX],low[MAX],ln[MAX],tim;
void dfs(int u,int ff)
{
if(u<=n)dfn[u]=low[u]=++tim,ln[tim]=u;
else dfn[u]=1e9,low[u]=0;
p[0][u]=ff;
for(int i=1;i<20;++i)p[i][u]=p[i-1][p[i-1][u]];
for(int i=h[u];i;i=e[i].next)
dfs(e[i].v,u),dfn[u]=min(dfn[u],dfn[e[i].v]),low[u]=max(low[u],low[e[i].v]);
}
int rt[MAX],S[MAX],top;
struct Node{int ls,rs,v;}t[MAX*20];
int num;
void modify(int &x,int l,int r,int p)
{
t[++num]=t[x];++t[x=num].v;if(l==r)return;
int mid=(l+r)>>1;
if(p<=mid)modify(t[x].ls,l,mid,p);
else modify(t[x].rs,mid+1,r,p);
}
int Query(int A,int B,int l,int r,int K)
{
if(l==r)return S[l];
int mid=(l+r)>>1,sum=t[t[A].rs].v-t[t[B].rs].v;
if(sum>=K)return Query(t[A].rs,t[B].rs,mid+1,r,K);
else return Query(t[A].ls,t[B].ls,l,mid,K-sum);
}
int main()
{
n=read();m=read();Q=read();
for(int i=1;i<=n;++i)S[i]=a[i]=read();
sort(&S[1],&S[n+1]);top=unique(&S[1],&S[n+1])-S-1;
for(int i=1;i<=n;++i)a[i]=lower_bound(&S[1],&S[top+1],a[i])-S;
for(int i=1;i<=m;++i)
{
int u=read(),v=read(),w=read();
E[i]=(edge){u,v,w};
}
sort(&E[1],&E[m+1]);
for(int i=1;i<=n;++i)f[i]=i;tot=n;
for(int i=1;i<=m;++i)
{
int u=getf(E[i].u),v=getf(E[i].v);
if(u==v)continue;++tot;
f[tot]=f[u]=f[v]=tot;dis[tot]=E[i].w;
Add(tot,u);Add(tot,v);
}
dfs(tot,0);
for(int i=1;i<=n;++i)modify(rt[i]=rt[i-1],1,top,a[ln[i]]);
int lans=0;
while(Q--)
{
int v=read(),x=read(),K=read();
if(lans!=-1)v^=lans,x^=lans,K^=lans;
for(int i=19;~i;--i)
if(p[i][v]&&dis[p[i][v]]<=x)
v=p[i][v];
if(low[v]-dfn[v]+1<K)lans=-1;
else lans=Query(rt[low[v]],rt[dfn[v]-1],1,top,K);
printf("%d\n",lans);
}
return 0;
}
【BZOJ3551】Peaks加强版(Kruskal重构树,主席树)的更多相关文章
- [BZOJ3551][ONTAK2010]Peaks(加强版)(Kruskal重构树,主席树)
3551: [ONTAK2010]Peaks加强版 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 2438 Solved: 763[Submit][ ...
- 【BZOJ-3545&3551】Peaks&加强版 Kruskal重构树 + 主席树 + DFS序 + 倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1202 Solved: 321[Submit][Sta ...
- BZOJ.3551.[ONTAK2010]Peaks加强版(Kruskal重构树 主席树)
题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. 强制在线. \ ...
- luoguP4197:Peaks(Kruskal重构树+主席树)或者(点分树+离线)
题意:有N座山,M条道路.山有山高,路有困难值(即点权和边权).现在Q次询问,每次给出(v,p),让求从v出发,只能结果边权<=p的边,问能够到达的山中,第K高的高度(从大到小排序). 思路:显 ...
- BZOJ3551 Peaks加强版 [Kruskal重构树,主席树]
BZOJ 思路 我觉得这题可持久化线段树合并也可以做 我觉得这题建出最小生成树之后动态点分治+线段树也可以做 还是学习一下Kruskal重构树吧-- Kruskal重构树,就是在做最小生成树的时候,如 ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
- 【BZOJ 3551】[ONTAK2010] Peaks加强版 Kruskal重构树+树上倍增+主席树
这题真刺激...... I.关于Kruskal重构树,我只能开门了,不过补充一下那玩意还是一棵满二叉树.(看一下内容之前请先进门坐一坐) II.原来只是用树上倍增求Lca,但其实树上倍增是一种方法,L ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 Kruskal重构树+dfs序+主席树+倍增
建出来 $Kruskal$ 重构树. 将询问点向上跳到深度最小,且合法的节点上. 那么,得益于重构树优美的性质,这个最终跳到的点为根的所有子节点都可以与询问点互达. 对于子树中求点权第 $k$ 大的问 ...
- BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增
题目描述 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只 ...
- luogu4197 Peaks (kruskal重构树+主席树)
按照边权排序建出kruskal重构树,每次就变成了先找一个权值<=x的最远的祖先,然后看这个子树的第k小.离散化一下,在dfs序上做主席树即可 而且只需要建叶节点的主席树 注意输出的是第k小点的 ...
随机推荐
- Netty源码分析第2章(NioEventLoop)---->第4节: NioEventLoop线程的启动
Netty源码分析第二章: NioEventLoop 第四节: NioEventLoop线程的启动 之前的小节我们学习了NioEventLoop的创建以及线程分配器的初始化, 那么NioEvent ...
- eclipse创建spring boot项目加载不到application.properties配置文件
在配置文件application.properties中修改了端口号,但重启服务后发现端口号并没有跟着改变,发现是项目启动时没有加载application.properties文件导致 解决:项目-& ...
- ActiveMQ笔记:管理和监控
ActiveMQ提供了比较丰富的监控和管理工具.在ActiveMQ的网页里(http://activemq.apache.org/how-can-i-monitor-activemq.html)提到了 ...
- 启动Nodejs服务
vs code 中间创建 1. settings.json { , { , { 'Content-Type': 'text/plain;charset=utf-8' })
- Spring Cloud限流思路及解决方案
转自: http://blog.csdn.net/zl1zl2zl3/article/details/78683855 在高并发的应用中,限流往往是一个绕不开的话题.本文详细探讨在Spring Clo ...
- 数据库之python操作mysql
目录 一.pymysql 二.SQLAchemy 2.操作使用 (1)连接数据库 (2)执行原生SQL语句 (3)ORM操作-数据表操作 (4)ORM操作-数据行操作 (5)更多例子 一.pymysq ...
- Beta冲刺第二周王者荣耀交流协会第五次会议
1.立会照片 成员:王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐. master:王磊 2.时间跨度: 2017年11月21日 15:00 — 15:17,总计17分钟. 3.地点: 一食堂 ...
- TeamWork#3,Week5,Bing Input Method vs Sogou Input Method
现在电脑上用五笔的用户越来越少了,好的拼音输入法也是难求.必应输入法的前身英库拼音输入法来自微软亚洲研究院的多项基础研究成果.最新的必应输入法不仅保留了英库拼音输入法的各项优势,还结合了必应的搜索体验 ...
- 第一次作业——MathExam285
MathExam285 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 • Estimate ...
- VirtualBox安装增强功能
一.安装依赖包 #yum install kernel-headers #yum install kernel-devel #yum install gcc* #yum install make 二. ...