[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条路径,每条路径有一个困 ...
随机推荐
- 【HIHOCODER 1599】逃离迷宫4
描述 小Hi被坏女巫抓进一座由无限多个格子组成的矩阵迷宫. 小Hi一开始处于迷宫(x, y)的位置,迷宫的出口在(a, b).小Hi发现迷宫被女巫施加了魔法,假设当前他处在(x, y)的位置,那么他只 ...
- poj 3614 伪素数问题
题意:1.p不是素数 2.(a^p)%p=a 输出yes 不满足输出no 思路: 判断素数问题,直接暴力判断 bool is_prime(int n) { for(int i=2;i*i<= ...
- ROM,PROM,EPROM,EEPROM及FLASH存储器的区别
在微机的发展初期,BIOS都存放在ROM(Read Only Memory,只读存储器)中.ROM内部的资料是在ROM的制造工序中,在工厂里用特殊的方法被烧录进去的,其中的内容只能读不能改,一旦烧录进 ...
- MediaStore类的使用
安卓系统会在每次开机之后扫描所有文件并分类整理存入数据库,记录在MediaStore这个类里,通过这个类就可以快速的获得相应类型的文件. 当然这个类只是给你一个uri,提取文件的操作还是要通过Curo ...
- POJ 3241 曼哈顿距离最小生成树 Object Clustering
先上几个资料: 百度文库有详细的分析和证明 cxlove的博客 TopCoder Algorithm Tutorials #include <cstdio> #include <cs ...
- excludeFromRecents标签
Android:excludeFromRecents控制在不在recent列表中显示. true时不显示:false显示,默认. 运行如下activity后,不会显示在recent列表中. <a ...
- [转]netstat -tnl 列出监听中的连接,查看端口是否开启
任何网络服务的后台进程都会打开一个端口,用于监听接入的请求. 这些正在监听的套接字也和连接的套接字一样,也能被 netstat 列出来. 参数 tnl, 现在我们可以看到处于监听状态的 TCP 端口和 ...
- javascript学习笔记 - 引用类型 Function
五 Function类型 每个函数都时Function类型的实例.函数也是对象. 声明函数: function func_name () {} //javascript解析器会在程序执行时率先读取函数 ...
- Java分页内容实例详解
首先定义一个fruit表,表里含有很多数据: 定义一个数据文件: public class Fruit { public String getIds() { return ids; } public ...
- Java接口抽象类
抽象类中的方法可以实现,接口中的方法只能声明,不能实现.抽象类的成员变量可以为各种类型,接口的变量只能为public static final.抽象类可以有静态方法和静态代码块,接口不能有.一个类只能 ...