题链:
http://www.lydsy.com/JudgeOnline/problem.php?id=3545
http://www.lydsy.com/JudgeOnline/problem.php?id=3551(同题,强制在线,题解)
题解:
最小生成树 Kruskal,线段树(合并),离线
首先把询问和边放在一起,按权值大小从小到大排序。
然后对每个点建一棵权值线段树,维护当前联通块里的海拔权值区间内的山的个数
然后按照 Kruskal 算法合并联通块,并且合并两个联通块对应的线段树(Merge操作看代码,感觉很暴力)。
然后对于一个枚举到的询问,其起点所在的联通块里的点一定是可以到达的,
所以就用线段树查询该联通块里的第k高的山就好了。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 100500
using namespace std;
struct Oper{
int type,w,a,b;
bool operator <(const Oper &rtm) const{
if(w!=rtm.w) return w<rtm.w;
return type<rtm.type;
}
}O[MAXN*10];
struct SGT{
int rt[MAXN],ls[MAXN*50],rs[MAXN*50],cnt[MAXN*50],sz;
void Modify(int &u,int l,int r,int p){
if(!u) u=++sz;
if(l==r){cnt[u]++; return;}
int mid=(l+r)>>1; cnt[u]++;
if(p<=mid) Modify(ls[u],l,mid,p);
else Modify(rs[u],mid+1,r,p);
}
int Merge(int u,int v){
if(!u||!v) return u+v;
cnt[u]+=cnt[v];
ls[u]=Merge(ls[u],ls[v]);
rs[u]=Merge(rs[u],rs[v]);
return u;
}
int Query(int u,int l,int r,int p){
if(l==r) return l;
int mid=(l+r)>>1;
if(p<=cnt[rs[u]]) return Query(rs[u],mid+1,r,p);
else return Query(ls[u],l,mid,p-cnt[rs[u]]);
}
}T;
int Fa[MAXN],H[MAXN],ANS[5*MAXN];
int N,M,Q,Ont;
void read(int &x){
static int f; static char ch;
x=0; f=1; ch=getchar();
while(ch<'0'||'9'<ch){if(ch=='-') f=-1; ch=getchar();}
while('0'<=ch&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
x=x*f;
}
int find(int x){
return x==Fa[x]?x:Fa[x]=find(Fa[x]);
}
int main(){
static int tmp[MAXN],tnt=0;
read(N); read(M); read(Q);
for(int i=1;i<=N;i++)
Fa[i]=i,read(H[i]),tmp[++tnt]=H[i];
for(int i=1;i<=M;i++)
read(O[++Ont].a),read(O[Ont].b),read(O[Ont].w),O[Ont].type=0;
for(int i=1;i<=Q;i++)
read(O[++Ont].a),read(O[Ont].w),read(O[Ont].b),O[Ont].type=i;
sort(tmp+1,tmp+tnt+1); tnt=unique(tmp+1,tmp+tnt+1)-tmp-1;
for(int i=1;i<=N;i++)
H[i]=lower_bound(tmp+1,tmp+tnt+1,H[i])-tmp,
T.Modify(T.rt[i],1,tnt,H[i]);
sort(O+1,O+Ont+1);
for(int i=1,f,fa,fb,p;i<=Ont;i++){
if(O[i].type){
f=find(O[i].a);
if(T.cnt[T.rt[f]]<O[i].b)
ANS[O[i].type]=-1;
else p=T.Query(T.rt[f],1,tnt,O[i].b),ANS[O[i].type]=tmp[p];
}
else{
fa=find(O[i].a); fb=find(O[i].b);
if(fa==fb) continue; Fa[fb]=fa;
T.rt[fa]=T.Merge(T.rt[fa],T.rt[fb]);
}
}
for(int i=1;i<=Q;i++) printf("%d\n",ANS[i]);
return 0;
}
●BZOJ 3545 [ONTAK2010]Peaks(离线)的更多相关文章
-
BZOJ 3545: [ONTAK2010]Peaks( BST + 启发式合并 + 并查集 )
这道题很好想, 离线, 按询问的x排序从小到大, 然后用并查集维护连通性, 用平衡树维护连通块的山的权值, 合并就用启发式合并.时间复杂度的话, 排序是O(mlogm + qlogq), 启发式合并是 ...
-
BZOJ 3545: [ONTAK2010]Peaks [Splay启发式合并]
3545: [ONTAK2010]Peaks 题意:带权图,多组询问与一个点通过边权\(\le x\)的边连通的点中点权k大值 又读错题了,输出点一直WA,问的是点权啊 本题加强版强制在线了,那这道题 ...
-
BZOJ 3545: [ONTAK2010]Peaks 启发式合并 + 离线 + Splay
Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询 ...
-
BZOJ.3545.[ONTAK2010]Peaks(线段树合并)
题目链接 \(Description\) 有n个座山,其高度为hi.有m条带权双向边连接某些山.多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少. \(Solut ...
-
bzoj 3545: [ONTAK2010]Peaks
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1124 Solved: 304[Submit][Status][Discuss] Descripti ...
-
bzoj 3545: [ONTAK2010]Peaks Kruskal重构树
题目: 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经 ...
-
BZOJ 3551: [ONTAK2010]Peaks加强版 [Kruskal重构树 dfs序 主席树]
3551: [ONTAK2010]Peaks加强版 题意:带权图,多组询问与一个点通过边权\(\le lim\)的边连通的点中点权k大值,强制在线 PoPoQQQ大爷题解传送门 说一下感受: 容易发现 ...
-
BZOJ 3551/3545: [ONTAK2010]Peaks加强版 (Kruskal树+dfs序上的主席树+倍增)
Orz PoPoQQQ 学到了维护子树信息的时候用dfsdfsdfs序套主席树节省线段树空间. 学到了怎么用指针写可持久化线段树-emmm- CODE 只贴上3551加强版带强制在线的代码 #incl ...
-
bzoj 3551: [ONTAK2010]Peaks加强版
Description [题目描述]同3545 Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来 ...
随机推荐
-
精彩 .NET 2015
英文原文:Understanding .NET 2015 Understanding 翻译为了解或理解,对于 .NET 来说,2015 年注定会更加精彩,所以标题就用了"精彩"这个 ...
-
destoon公司搜索页面显示公司类型
首先找到前台模板文件:/template/default/company/search.htm 看到51行 {template 'list-company', 'tag'} 打开 /template/ ...
-
跨进程(同一app不同进程之间通信)——Android自动化测试学习历程
视频地址:http://study.163.com/course/courseLearn.htm?courseId=712011#/learn/video?lessonId=877122&co ...
-
Cookie、Session
Cookie.Session Cookie 保存在浏览器端. 4kb 只能保存字符串,还不能是中文. 获取:Request.getCookies(); 设置时间:setMaxAge(); 小于零是浏览 ...
-
怎样使用CMenu类
CMenu类从CObject类派生而来.为什么要使用CMenu类呢?AppWzard不是把菜单做好了吗?在资源编辑器上修改菜单不是很方便吗? 我是个vc++初学者,自从当斑竹以来,天天看贴子, ...
-
C#生成DLL文件
使用csc命令将.cs文件编译成.dll的过程 很多时候,我们需要将.cs文件单独编译成.dll文件, 操作如下: 打开命令窗口->输入cmd到控制台->cd C:\WINDOWS\Mic ...
-
删除iPhone图片,提示“没有删除此项目的权限”
解决方法:设置-照片与相机-iCloud照片图库-关闭 (IOS10)
-
python2/python3 内存中打包/压缩文件
python2:(包含压缩选项,如果只打包,可以调整zipfile.ZIP_DEFLATED) import zipfile import StringIO class InMemoryZip(obj ...
-
vcs编译verilog/sysverilog并执行
命令: sverilog:表示支持systemverilog,如果只编译verilog不需要加 test.sv :这个可以是一个systemverilog/verilog文件,也可以是一个filel ...
-
WEB架构师成长之路 三
Web架构师究竟都要学些什么?具备哪些能力呢?先网上查查架构师的大概的定义,参见架构师修炼之道这篇文章,写的还不错,再查查公司招聘Web架构师的要求. 总结起来大概有下面几点技能要求: 一. 架构师有 ...