Kruskal重构树+树链剖分求LCA+主席树 RE 0pts求调(玄关)
  • 板块P4197 Peaks
  • 楼主lunjiahao
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/3/21 10:47
  • 上次更新2024/3/21 16:09:32
查看原帖
Kruskal重构树+树链剖分求LCA+主席树 RE 0pts求调(玄关)
779970
lunjiahao楼主2024/3/21 10:47
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5,M=5e5+5;
int n,m,Q,a[N],b[N],tot,fa[N],w[N];
vector<int> g[N];
int cnt,f[N],dep[N],siz[N],hs[N],top[N],id[N],s[N];
int CNT,ls[N<<5],rs[N<<5],t[N<<5],rt[N<<5];
struct Edge
{
	int u,v,w;
}e[M];
bool cmp(Edge a,Edge b)
{
	return a.w<b.w;
}
int find(int x)
{
	return fa[x]==x?x:fa[x]=find(fa[x]);
}
void Kruskal()
{
	tot=n;
	for(int i=1;i<=n<<1;i++) fa[i]=i;
	sort(e+1,e+1+m,cmp);
	for(int i=1;i<=m;i++)
	{
		int u=find(e[i].u),v=find(e[i].v);
		if(u==v) continue;
		fa[u]=fa[v]=++tot;
		g[tot].push_back(u);
		g[tot].push_back(v);
		w[tot]=e[i].w;
	}
}
void dfs1(int u,int fath)
{
	f[u]=fath;
	dep[u]=dep[fath]+1;
	siz[u]=1;
	hs[u]=-1;
	for(auto v:g[u])
	{
		if(v==fath) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(hs[u]==-1||siz[v]>siz[hs[u]]) hs[u]=v;
	}
}
void dfs2(int u,int t)
{
	top[u]=t;
	id[u]=++cnt;
	s[cnt]=a[u];
	if(hs[u]!=-1) dfs2(hs[u],t);
	for(auto v:g[u])
		if(v!=hs[u]&&f[u]!=v)
			dfs2(v,v);
}
int LCA(int u,int v)
{
	while(top[u]^top[v])
	{
		if(dep[top[u]]<dep[top[v]]) swap(u,v);
		u=fa[top[u]];
	}
	if(dep[u]<dep[v]) swap(u,v);
	return v;
}
void build(int &o,int l,int r)
{
	o=++CNT;
	if(l==r)
	{
		return;
	}
	int mid=(l+r)>>1;
	build(ls[o],l,mid);
	build(rs[o],mid+1,r);
}
void update(int &o,int pre,int l,int r,int x)
{
	o=++CNT;
	t[o]=t[pre]+1,ls[o]=ls[pre],rs[o]=rs[pre];
	if(l==r) return;
	int mid=(l+r)>>1;
	if(x<=mid) update(ls[o],ls[pre],l,mid,x);
		else update(rs[o],rs[pre],mid+1,r,x);
}
int query(int l,int r,int u,int v,int k)
{
	if(l==r) return l;
	if(t[v]-t[u]<k) return -1;
	int mid=(l+r)>>1,x=t[rs[v]]-t[rs[u]];
	if(x<k) return query(l,mid,ls[u],ls[v],k-x);
		else return query(mid+1,r,rs[u],rs[v],k);
}
signed main()
{
	scanf("%d%d%d",&n,&m,&Q);
	for(int i=1;i<=n;i++)
		scanf("%d",&a+i),b[i]=a[i];
	sort(b+1,b+1+n);
	int len=unique(b+1,b+1+n)-b-1;
	for(int i=1;i<=n;i++)
		a[i]=lower_bound(b+1,b+1+len,a[i])-b;
	for(int i=1;i<=m;i++)
		scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
	Kruskal();
	for(int i=tot;i;i--)
		if(!dep[i]) dfs1(i,0),dfs2(i,i);
	build(rt[0],1,len);
	for(int i=1;i<=tot;i++) 
		update(rt[i],rt[i-1],1,len,s[i]);
	while(Q--)
	{
		int u,v,k;
		scanf("%d%d%d",&u,&v,&k);
		int lca=LCA(u,v);
		int ans=query(1,len,rt[id[lca]-1],rt[id[lca]+siz[lca]-1],k);
		printf("%d\n",ans);
	}
	return 0;
}

2024/3/21 10:47
加载中...