MLE求助卡空间,也有可能是其他问题
  • 板块P4197 Peaks
  • 楼主PCCP
  • 当前回复3
  • 已保存回复3
  • 发布时间2023/8/15 16:35
  • 上次更新2023/11/3 03:36:35
查看原帖
MLE求助卡空间,也有可能是其他问题
310773
PCCP楼主2023/8/15 16:35

RT,克鲁斯卡尔重构树+树剖+主席树,第一个点过了,其他 MLE 了,感觉已经无法自己继续优化,特来求助谷内大佬。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
#include<set>
using namespace std;
const int N=1e5+10;
const int M=5e5+10;
int n,m,q,h[N],a[N<<1],fa[N],cnt,to[N<<1][2];
struct edge{
	int x,y,w;
}e[M];
bool cmp(edge x,edge y){
	return x.w<y.w;
}
int find(int x){
	if(fa[x]==x){
		return x;
	}
	return fa[x]=find(fa[x]);
}
void unify(int x,int y){
	fa[find(y)]=find(x);
}
int fat[N],siz[N],son[N],top[N],dfo[N],seq[N];
void dfs1(int x,int f){
	fat[x]=f,siz[x]=1;
	for(int i=0;i<2;i++){
		int v=to[x][i];
		if(!v){
			continue;
		}
		dfs1(v,x);
		siz[x]+=siz[v];
		if(siz[v]>siz[son[x]]){
			son[x]=v;
		}
	}
}
void dfs2(int x,int t){
	dfo[x]=++cnt,top[x]=t,seq[cnt]=x;
	if(son[x]){
		dfs2(son[x],t);
	}
	for(int i=0;i<2;i++){
		int v=to[x][i];
		if(!v||v==son[x]){
			continue;
		}
		dfs2(v,v);
	}
}
int gr(int x,int k){
	while(a[fat[top[x]]]<=k&&fat[top[x]]!=0){
		x=fat[top[x]];
	}
	int l=dfo[top[x]],r=dfo[x],res=x;
	while(l<=r){
		int mid=(l+r)>>1;
		if(a[seq[mid]]<=k){
			r=mid-1;
			res=seq[mid]; 
		}
		else{
			l=mid+1;
		}
	}
	return res;//返回编号为res的节点
}
int root[N<<1],tot;
vector <int> num;
struct node{
	int l,r,cnt;
}tr[N*18];
int get(int x){
	return lower_bound(num.begin(),num.end(),x)-num.begin();
}
int build(int l,int r){
	int p=++tot;
	if(l==r){
		return p;
	}
	int mid=(l+r)>>1;
	tr[p].l=build(l,mid);
	tr[p].r=build(mid+1,r);
	return p;
}
int insert(int p,int l,int r,int x){
	int q=++tot;
	tr[q]=tr[p];
	if(l==r){
		tr[q].cnt++;
		return q;
	}
	int mid=(l+r)>>1;
	if(x<=mid){
		tr[q].l=insert(tr[p].l,l,mid,x);
	}
	else{
		tr[q].r=insert(tr[p].r,mid+1,r,x);
	} 
	tr[q].cnt=tr[tr[q].l].cnt+tr[tr[q].r].cnt;
	return q;
}
int query(int q,int p,int l,int r,int k){
	if(l==r){
		return r;
	}
	int cnt=tr[tr[q].l].cnt-tr[tr[p].l].cnt;
	int mid=(l+r)>>1;
	if(k<=cnt){
		return query(tr[q].l,tr[p].l,l,mid,k);
	}
	else{
		return query(tr[q].r,tr[p].r,mid+1,r,k-cnt);
	}
}
int main(){
	scanf("%d%d%d",&n,&m,&q);
	cnt=n;
	for(int i=1;i<=n;i++){
		scanf("%d",&h[i]);
		num.push_back(h[i]);
	}
	sort(num.begin(),num.end());
	num.erase(unique(num.begin(),num.end()),num.end());
	for(int i=1;i<=n*2;i++){
		fa[i]=i,a[i]=0;
	}
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].w);
	}
	sort(e+1,e+m+1,cmp);
	int x,y,z;
	for(int i=1;i<=m;i++){
		x=find(e[i].x),y=find(e[i].y);
		if(x!=y){
			++cnt;
			unify(cnt,x),unify(cnt,y);
			to[cnt][0]=x,to[cnt][1]=y;
			a[cnt]=e[i].w;
		}
	}
	cnt=0;
	dfs1(2*n-1,0);
	dfs2(2*n-1,2*n-1);
	tot=0;
	root[0]=build(0,num.size()-1);
	for(int i=1;i<=cnt;i++){
		if(seq[i]<=n){
			root[i]=insert(root[i-1],0,num.size()-1,get(h[seq[i]]));
		}
		else{
			root[i]=root[i-1];
		}
	}
	while(q--){
		scanf("%d%d%d",&x,&y,&z);
		int rt=gr(x,y);
		if(tr[root[dfo[rt]+siz[rt]-1]].cnt-tr[root[dfo[rt]-1]].cnt<z){
			printf("-1\n");
		}
		else{
			z=tr[root[dfo[rt]+siz[rt]]].cnt-tr[root[dfo[rt]-1]].cnt-z;
			printf("%d\n",num[query(root[dfo[rt]+siz[rt]-1],root[dfo[rt]-1],0,num.size()-1,z)]);
		}
	}
}
2023/8/15 16:35
加载中...