【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小点的 ...
随机推荐
- A* 寻路的八个变种
变种 1 - 束搜索(Beam Search) 在 A* 算法的住循环中,OPEN 集存储可能需要搜索的节点,用来以查找路径. 束搜索是 A* 的变体,它限制了OPEN集的大小. 如果集合变得太大,则 ...
- tensorflow-gpu在win10下的安装
参考:https://blog.csdn.net/gyp2448565528/article/details/79451212 按照原博主的方法在自己的机器上会有一点小错误,下面的方法略有不同 环境: ...
- selenium 基本常用操作
from selenium import webdriverfrom selenium.webdriver.common.action_chains import ActionChains #鼠标操作 ...
- SQLMAP学习笔记1 access注入
SQLMAP学习笔记1 access注入 Sqlmap是开源的自动化SQL注入工具,由Python写成,具有如下特点: 完全支持MySQL.Oracle.PostgreSQL.Microsoft S ...
- 琴声不等式--jensen
(来自百度百科) 1. 凹函数,不加权 2. 凹函数,加权 3. 凸函数,不加权 4. 凸函数,加权 应用 在EM算法Q函数的推导中,用到了第二个不等式(凹函数,加权)
- React Native移动开发实战-2-如何调试React Native项目
在实际开发中,还有一个影响开发效率的重要因素:调试. 在1.4.3节中已经介绍了Enable Live Debugger的使用.本节来介绍另一个非常重要的调试选项:Debug JSRemotely选项 ...
- Bitcoin Core P2P网络层
目录 数据结构 节点发现和节点连接 地址管理 节点发现 节点连接 插口(Sockets)和消息 Socket线程 (net.cpp) 消息线程 ProcessMessages (net_process ...
- 实验三 敏捷开发和XP实验
课程:Java程序设计实验 班级:1352 姓名: 于佳心 学号:20135206 成绩: 指导教师:娄嘉鹏 ...
- DataTime日期格式化
C# DateTime日期格式化 在C#中DateTime是一个包含日期.时间的类型,此类型通过ToString()转换为字符串时,可根据传入给Tostring()的参数转换为多种字符串格式. 目录 ...
- POJ 1112 Team Them Up! 二分图判定+01背包
题目链接: http://poj.org/problem?id=1112 Team Them Up! Time Limit: 1000MSMemory Limit: 10000K 问题描述 Your ...