玄关求助25分
  • 板块P4197 Peaks
  • 楼主fcy20180201
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/6/27 18:50
  • 上次更新2024/6/27 21:28:23
查看原帖
玄关求助25分
866154
fcy20180201楼主2024/6/27 18:50

做法:离线+线段树合并

#include<bits/stdc++.h>
using namespace std;
const int N=1e7+5,M=1e9;
int n,m,q,h,fa[100005],rt[100005],tr[N],ls[N],rs[N],tot;
void update(int &cur,int l,int r,int loc){
	tr[cur=++tot]=1;
	if(l==r)return ;
	int mid=(l+r)>>1;
	if(loc<=mid)update(ls[cur],l,mid,loc);
	else update(rs[cur],mid+1,r,loc);
	return ;
}
int ff(int u){return fa[u]==u?u:fa[u]=ff(fa[u]);}
int merge(int u,int v){
	if(!u || !v)return u|v;
	ls[u]=merge(ls[u],ls[v]);
	rs[u]=merge(rs[u],rs[v]);
	tr[u]=tr[ls[u]]+tr[rs[u]];
	return u;
}
int query(int &cur,int l,int r,int val){
	if(!cur)cur=++tot;
	if(l==r)return l;
	int mid=(l+r)>>1;
	if(val>tr[rs[cur]])return query(ls[cur],l,mid,val-tr[rs[cur]]);
	else return query(rs[cur],mid+1,r,val);
}
struct node{
	int u,v,w;
}e[500005],qs[500005];
bool operator <(const node &x,const node &y){return x.w<y.w;}
int main(){
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=n;i++){
		scanf("%d",&h);
		update(rt[i],1,M,h);
		fa[i]=i;
	}
	for(int i=1;i<=m;i++)scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
	sort(e+1,e+m+1);
	for(int i=1;i<=q;i++)scanf("%d%d%d",&qs[i].u,&qs[i].w,&qs[i].v);
	sort(qs+1,qs+q+1);
	for(int i=1,j=1;i<=q;i++){
		while(j<=m && e[j].w<=qs[i].w){
			int u=ff(e[j].u),v=ff(e[j].v);
			if(u!=v)fa[v]=u,merge(rt[u],rt[v]);
			j++;
		}
		int u=ff(qs[i].u);
		printf("%d\n",tr[rt[u]]<qs[i].v?-1:query(rt[u],1,M,qs[i].v));
	}
	return 0;
}

2024/6/27 18:50
加载中...