题目大意:
  一个图上有$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的更多相关文章

  1. bzoj 3545&&3551: [ONTAK2010]Peaks &&加强版 平衡树&&并查集合并树&&主席树

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 635  Solved: 177[Submit][Stat ...

  2. BZOJ 3545: [ONTAK2010]Peaks( BST + 启发式合并 + 并查集 )

    这道题很好想, 离线, 按询问的x排序从小到大, 然后用并查集维护连通性, 用平衡树维护连通块的山的权值, 合并就用启发式合并.时间复杂度的话, 排序是O(mlogm + qlogq), 启发式合并是 ...

  3. BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]

    3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...

  4. BZOJ 3545: [ONTAK2010]Peaks [Splay启发式合并]

    3545: [ONTAK2010]Peaks 题意:带权图,多组询问与一个点通过边权\(\le x\)的边连通的点中点权k大值 又读错题了,输出点一直WA,问的是点权啊 本题加强版强制在线了,那这道题 ...

  5. bzoj3545: [ONTAK2010]Peaks 重构树 主席树

    题目链接 bzoj3545: [ONTAK2010]Peaks 题解 套路重构树上主席树 代码 #include<cstdio> #include<algorithm> #de ...

  6. 【BZOJ3545】 [ONTAK2010]Peaks

    BZOJ3545 [ONTAK2010]Peaks Solution 既然会加强版,直接把强制在线的操作去掉就好了. 代码实现 #include<stdio.h> #include< ...

  7. 【BZOJ3551】 [ONTAK2010]Peaks加强版

    BZOJ3551 [ONTAK2010]Peaks加强版 Solution Kruscal重构树后发现可以对于小于的离散化然后倍增+主席树找到上一个的可行解. 然后就可以了. 如果数组开的不好,容易在 ...

  8. [ONTAK2010]Peaks kruskal重构树,主席树

    [ONTAK2010]Peaks kruskal重构树练手题. LG传送门竟然不强制在线?看到离线水过很不爽:B站强制在线版传送门 看到"询问从点\(v\)开始只经过困难值小于等于\(x\) ...

  9. bzoj 3545/3551: [ONTAK2010]Peaks -- 主席树,最小生成树,倍增

    3545: [ONTAK2010]Peaks Time Limit: 10 Sec  Memory Limit: 128 MB Description 在Bytemountains有N座山峰,每座山峰 ...

  10. 【BZOJ3551】[ONTAK2010]Peaks加强版 最小生成树+DFS序+主席树

    [BZOJ3545][ONTAK2010]Peaks Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困 ...

随机推荐

  1. HashMap存储原理

    1.    HashMap概述 HashMap是基于哈希表的Map接口的非同步实现.此实现提供所有可选的映射操作,并允许使用null值和null键.此类不保证映射的顺序,特别是它不保证该顺序恒久不变. ...

  2. Applied Nonparametric Statistics-lec10

    Ref:https://onlinecourses.science.psu.edu/stat464/print/book/export/html/14 估计CDF The Empirical CDF ...

  3. ASCII码表含义

    在计算机中,所有的数据在存储和运算时都要使用二进制数表示(因为计算机用高电平和低电平分别表示1和0),例如,像a.b.c.d这样的52个字母(包括大写)以及0.1等数字还有一些常用的符号(例如*.#. ...

  4. Linux学习-什么是例行性工作排程

    那么 Linux 的例行性工作是如何进行排程的呢?所谓的排程就是将这些工作安排执行的流程之意! 咱们的 Linux 排程就是透过 crontab 与 at 这两个东西! Linux 工作排程的种类: ...

  5. VR开发的烦恼——范围限制

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/52230865 作者:car ...

  6. Spring学习总结(20)——Spring加载多个项目properties配置文件问题解决

    多数的鲜为人知方法都是因为有着罕见的应用,就比如说Spring中PropertyPlaceholderConfigurer这个类,它是用来解析Java Properties属性文件值,并提供在spri ...

  7. Objective-C中的一些特殊的数据类型

    nil nil和C语言的NULL相同,在objc/objc.h中定义.nil表示一个Objctive-C对象,这个对象的指针指向空(没有东西就是空). Nil  首字母大写的Nil和nil有一点不一样 ...

  8. 大数据学习——sparkSql对接hive

    1.   安装mysql 2.   上传.解压.重命名 2.1.  上传 在随便一台有hadoop环境的机器上上传安装文件 su - hadoop rz –y 2.2.  解压 解压缩:apache- ...

  9. MySQL常见数据库引擎及比较?

    一:MySQL存储引擎简介 MySQL有多种存储引擎,每种存储引擎有各自的优缺点,大家可以择优选择使用:MyISAM.InnoDB.MERGE.MEMORY(HEAP).BDB(BerkeleyDB) ...

  10. 高并发下的HashMap,ConcurrentHashMap

    参照: http://mp.weixin.qq.com/s/dzNq50zBQ4iDrOAhM4a70A http://mp.weixin.qq.com/s/1yWSfdz0j-PprGkDgOomh ...