萌新求助MLE
  • 板块P4197 Peaks
  • 楼主dk_qwq
  • 当前回复0
  • 已保存回复0
  • 发布时间2023/10/19 20:39
  • 上次更新2023/11/2 12:43:16
查看原帖
萌新求助MLE
311306
dk_qwq楼主2023/10/19 20:39
#include<iostream>
#include<cstdio>
#include<vector>
#define pb push_back
#include<algorithm>
using namespace std;
// namespace INPUT{
// 	char buf[1<<20],*p1,*p2;
// 	#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
// }
// using namespace INPUT;
#define gc getchar
template<typename T>
T read(){
	T x=0,p=1;
	char ch=gc();
	for(;ch<'0'||ch>'9';ch=gc())
		if(ch=='-') p=-1;
	for(;'0'<=ch&&ch<='9';ch=gc())
		x=(x<<3)+(x<<1)+(ch^48);
	return x*p;
}
const int N=1e5+5;
const int M=N*17;
class SegTree{
	int lc[M],rc[M];
	int siz[M],tot;
	int insert(int u,int l,int r,int v){
		if(!u) u=++tot;
		siz[u]++;
		if(l==r) return u;
		int mid=(l+r)>>1;
		if(v<=mid) lc[u]=insert(lc[u],l,mid,v);
		if(mid<v) rc[u]=insert(rc[u],mid+1,r,v);
		return u;
	}
	int root[N];
	int query(int u,int l,int r,int k){
		if(l==r) return l;
		int mid=(l+r)>>1;
		if(siz[lc[u]]>=k) return query(lc[u],l,mid,k);
		else return query(rc[u],mid+1,r,k-siz[lc[u]]);
	}
	int Union(int u,int v){
		if(!u||!v) return u+v;
		siz[u]+=siz[v];
		lc[u]=Union(lc[u],lc[v]);
		rc[u]=Union(rc[u],rc[v]);
		return u;
	}
public:
	int L,R;
	void insert(int u,int v){
		root[u]=insert(root[u],L,R,v);
	}
	int query(int u,int k){
		if(siz[root[u]]<k) return -1;
		k=siz[root[u]]-k+1;
		return query(root[u],L,R,k);
	}
	void UnionRoot(int u,int v){
		root[u]=Union(root[u],root[v]);
	}
}T;
int fa[N],siz[N];
int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
struct Edge{
	int u,v,w;
	friend bool operator<(const Edge& a,const Edge& b){
		return a.w<b.w;
	}
};
struct Query{
	int v,x,k;
	int id;
	friend bool operator<(const Query& a,const Query& b){
		return a.x<b.x;
	}
};
vector<Edge>edges;
vector<Query>query;
void add(Edge ed){
	int u=find(ed.u),v=find(ed.v);
	if(u==v) return ;
	if(siz[u]<siz[v]) swap(u,v);

	T.UnionRoot(u,v);
	//union two tree
	fa[v]=u;
	siz[u]+=siz[v];
}
int n,m,q;
int ans[N*5];
int b[N];
int h[N];
int main(){
	// freopen("P4197.in","r",stdin);
	// freopen("P4197.out","w",stdout);
	n=read<int>(),m=read<int>(),q=read<int>();
	for(int i=1;i<=n;i++) fa[i]=i,siz[i]=1;
	for(int i=1;i<=n;i++) b[i]=h[i]=read<int>();
	sort(h+1,h+1+n);
	int sz=unique(h+1,h+1+n)-h-1;
	T.L=1,T.R=sz;
	for(int i=1;i<=n;i++) b[i]=lower_bound(h+1,h+1+sz,b[i])-h;
	for(int i=1;i<=n;i++) T.insert(i,b[i]);
	for(int i=1;i<=m;i++){
		int u=read<int>(),v=read<int>();
		edges.pb({u,v,read<int>()});
	}
	sort(edges.begin(), edges.end());
	for(int i=1;i<=q;i++){
		int v=read<int>(),x=read<int>();
		query.pb({v,x,read<int>(),i});
	}
	sort(query.begin(), query.end());
	int l=0;

	for(auto qe:query){
		int v=qe.v,x=qe.x,k=qe.k;
		while(l<int(edges.size())&&edges[l].w<=x) add(edges[l++]);
		ans[qe.id]=T.query(find(v),k);
	}
	for(int i=1;i<=q;i++) printf("%d\n",ans[i]==-1?-1:h[ans[i]]);
}
/*
动态开点线段树:
支持合并 查询第k大值
插入
离散化h
*/
2023/10/19 20:39
加载中...