[ONTAK2010]Peaks
题目大意:
一个图上有$n(n\leq100000)$个带权点,$m(m\leq500000)$条带权边。有$q(q\leq500000)$组询问,每次询问从点$v$出发,只经过权值小于等于$x$的边能到达的点中,权值第$k$大的点权。
思路:
离线处理每个询问。将询问和边分别按权值排序,处理到当前询问时,将权值小于等于$x$的边加入到图中。用权值线段树维护每个连通块的权值。点的联通情况用并查集维护(相当于Kruskal),权值线段树直接合并。时间复杂度$O(n\log n+m\log m+q\log q+q\log n)$。
#include<cstdio>
#include<cctype>
#include<algorithm>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=,M=,Q=;
int h[N],tmp[N],ans[Q];
struct Edge {
int u,v,w;
bool operator < (const Edge &another) const {
return w<another.w;
}
};
Edge e[M];
struct Query {
int v,x,k,id;
bool operator < (const Query &another) const {
return x<another.x;
}
};
Query q[Q];
struct DisjointSet {
int anc[N];
int find(const int &x) {
return x==anc[x]?x:anc[x]=find(anc[x]);
}
void reset(const int &n) {
for(register int i=;i<=n;i++) anc[i]=i;
}
void merge(const int &x,const int &y) {
anc[find(y)]=find(x);
}
bool same(const int &x,const int &y) {
return find(x)==find(y);
}
};
DisjointSet s;
class SegmentTree {
private:
struct Node {
int val;
Node *left,*right;
Node(const int &v):val(v),left(NULL),right(NULL) {}
};
void modify(Node *&p,const int &b,const int &e,const int &x) {
p=new Node();
if(b==e) return;
const int mid=(b+e)>>;
if(x<=mid) modify(p->left,b,mid,x);
if(x>mid) modify(p->right,mid+,e,x);
}
public:
Node *root[N];
void reset(const int &n) {
for(register int i=;i<=n;i++) {
modify(root[i],,tmp[],h[i]);
}
}
void merge(Node *&p1,Node *const &p2) {
if(!p1) {
p1=p2;
return;
}
if(!p2) return;
p1->val+=p2->val;
merge(p1->left,p2->left);
merge(p1->right,p2->right);
delete p2;
}
int query(const Node *const &p,const int &b,const int &e,const int &k) const {
if(p->val<k) return -;
if(b==e) return b;
const int mid=(b+e)>>;
if(!p->right) return query(p->left,b,mid,k);
if(k<=p->right->val) return query(p->right,mid+,e,k);
return query(p->left,b,mid,k-p->right->val);
}
};
SegmentTree t;
inline void add_edge(const Edge &e) {
if(s.same(e.u,e.v)) return;
t.merge(t.root[s.find(e.u)],t.root[s.find(e.v)]);
s.merge(e.u,e.v);
}
int main() {
const int n=getint(),m=getint(),cnt_q=getint();
for(register int i=;i<=n;i++) {
tmp[i]=h[i]=getint();
}
std::sort(&tmp[],&tmp[n]+);
tmp[]=std::unique(&tmp[],&tmp[n]+)-&tmp[];
for(register int i=;i<=n;i++) {
h[i]=std::lower_bound(&tmp[],&tmp[tmp[]]+,h[i])-&tmp[];
}
for(register int i=;i<m;i++) {
const int u=getint(),v=getint(),w=getint();
e[i]=(Edge){u,v,w};
}
std::sort(&e[],&e[m]);
for(register int i=;i<cnt_q;i++) {
const int v=getint(),x=getint(),k=getint();
q[i]=(Query){v,x,k,i};
}
std::sort(&q[],&q[cnt_q]);
s.reset(n);
t.reset(n);
for(register int i=,p=;i<cnt_q;i++) {
while(p<m&&e[p].w<=q[i].x) add_edge(e[p++]);
ans[q[i].id]=t.query(t.root[s.find(q[i].v)],,tmp[],q[i].k);
}
for(register int i=;i<cnt_q;i++) {
printf("%d\n",~ans[i]?tmp[ans[i]]:-);
}
return ;
}
[ONTAK2010]Peaks的更多相关文章
- bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 635 Solved: 177[Submit][Stat ...
- BZOJ 3545: [ONTAK2010]Peaks( BST + 启发式合并 + 并查集 )
这道题很好想, 离线, 按询问的x排序从小到大, 然后用并查集维护连通性, 用平衡树维护连通块的山的权值, 合并就用启发式合并.时间复杂度的话, 排序是O(mlogm + qlogq), 启发式合并是 ...
- BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
- BZOJ 3545: [ONTAK2010]Peaks [Splay启发式合并]
3545: [ONTAK2010]Peaks 题意:带权图,多组询问与一个点通过边权\(\le x\)的边连通的点中点权k大值 又读错题了,输出点一直WA,问的是点权啊 本题加强版强制在线了,那这道题 ...
- bzoj3545: [ONTAK2010]Peaks 重构树 主席树
题目链接 bzoj3545: [ONTAK2010]Peaks 题解 套路重构树上主席树 代码 #include<cstdio> #include<algorithm> #de ...
- 【BZOJ3545】 [ONTAK2010]Peaks
BZOJ3545 [ONTAK2010]Peaks Solution 既然会加强版,直接把强制在线的操作去掉就好了. 代码实现 #include<stdio.h> #include< ...
- 【BZOJ3551】 [ONTAK2010]Peaks加强版
BZOJ3551 [ONTAK2010]Peaks加强版 Solution Kruscal重构树后发现可以对于小于的离散化然后倍增+主席树找到上一个的可行解. 然后就可以了. 如果数组开的不好,容易在 ...
- [ONTAK2010]Peaks kruskal重构树,主席树
[ONTAK2010]Peaks kruskal重构树练手题. LG传送门竟然不强制在线?看到离线水过很不爽:B站强制在线版传送门 看到"询问从点\(v\)开始只经过困难值小于等于\(x\) ...
- bzoj 3545/3551: [ONTAK2010]Peaks -- 主席树,最小生成树,倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MB Description 在Bytemountains有N座山峰,每座山峰 ...
- 【BZOJ3551】[ONTAK2010]Peaks加强版 最小生成树+DFS序+主席树
[BZOJ3545][ONTAK2010]Peaks Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困 ...
随机推荐
- JdbcTemplate实验
实验1:测试数据源 @Test public void test() throws SQLException { ApplicationContext ioc = new ClassPathXmlAp ...
- LeetCode(278)First Bad Version
题目 You are a product manager and currently leading a team to develop a new product. Unfortunately, t ...
- city Engine 建模
基本操作介绍 界面布局,文件组织 五个常见图层 常见规则,替换思想
- 新游发布:《Don't touch the color》
这是笨猫工作室最后一个Scratch 2.0游戏,经过笨猫工作室成员的不懈努力,游戏终于可以稳定运行.此次更新添加了最高分数显示,优化了系统流畅度.快来试玩吧!!! 卡搭蓝链:https://kada ...
- Linux学习-什么是例行性工作排程
那么 Linux 的例行性工作是如何进行排程的呢?所谓的排程就是将这些工作安排执行的流程之意! 咱们的 Linux 排程就是透过 crontab 与 at 这两个东西! Linux 工作排程的种类: ...
- 匈牙利算法 - Luogu 1963 变换序列
P1963 变换序列 题目描述 对于N个整数0,1,-,N-1,一个变换序列T可以将i变成Ti,其中:Ti∈{0,1,-,N-1}且 {Ti}={0,1,-,N-1}. x,y∈{0,1,-,N-1} ...
- Android之高效率截图
本文来自网易云社区 作者:孙圣翔 在一张Android手机上截图有好多办法,为了能够高效率的截图,我几乎把所有的方法都尝试了一般.走了好多路,也遇到了好多的问题. 只是想记录下这其中的不容易. 下面所 ...
- Selenium WebDriver- actionchians模拟鼠标悬停操作
#encoding=utf-8 import unittest import time from selenium import webdriver from selenium.webdriver i ...
- python学习-- 默认urls中 Path converter
默认Path converter Django2.0自带的PathConveter包括: str:匹配除了路径分隔符(/)之外的非空字符串,如果没有转换器,默认使用str作为转换器. int:匹配0及 ...
- 【Luogu】P2598狼和羊的故事(最小割转最大流)
题目链接 最小割水题.入点向白点连边,白点向白点.黑点和空点连边,空点向空点和黑点连边,黑点向黑点和汇点连边.然后跑最大流即可. 话说Fd最近怎么光做水题啊……一点用都没有……qwq 我太菜了,做完一 ...