50pts求助,Kruskal重构树+st表
查看原帖
50pts求助,Kruskal重构树+st表
478014
Yinsh楼主2023/1/31 20:15

已经调了很久了,没有数据,由于太菜自己造的又没有起丝毫作用,希望有人帮一下忙,提供hack数据或找一下错误,代码如下

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
struct node
{
	int x,y,z;
}bian[200010];
vector<int>g[200010];
int n,m,q,t;
int st[100010][21];
int lg[200010];
int p[200010];
int poi[200010];
int d[200010],f[200010][21];
int find(int x)
{
	if(x==p[x])return x;
	p[x]=find(p[x]);
	return p[x];//并查集 
}
void kru()
{
	int cnt=0;
	for(int i=1;i<=m;i++)
	{
		int x=bian[i].x,y=bian[i].y;
		if(find(x)==find(y))continue;
		cnt++;
		poi[cnt+n]=bian[i].z;
		g[cnt+n].push_back(find(x));
		g[cnt+n].push_back(find(y));
		g[find(x)].push_back(cnt+n);
		g[find(y)].push_back(cnt+n);
		p[find(x)]=cnt+n;
		p[find(y)]=cnt+n;
		if(cnt==n-1)return ;
	}//重构树 
}
void dfs(int x,int fa)
{
	d[x]=d[fa]+1;//求出每一个点在重构树上的深度 
	f[x][0]=fa;
	for(int i=1;i<=lg[n*2-1];i++)f[x][i]=f[f[x][i-1]][i-1];//求出每一个点向上能跳到的祖先节点 
	for(int i=0;i<g[x].size();i++)
	{
		int newnx=g[x][i];
		if(newnx==fa)continue;
		dfs(newnx,x);
	}
}
int lca(int x,int y)
{
	if(d[x]<=d[y])swap(x,y);
	for(int i=lg[n*2-1];i>=0;i--)
	{
		if(d[x]-(1<<i)>=d[y])x=f[x][i];
	}
	if(x==y)return x;
	for(int i=lg[n*2-1];i>=0;i--)
	{
		if(f[x][i]==f[y][i])continue;
		x=f[x][i];
		y=f[y][i];
	}//最近公共祖先 
	return f[x][0];
}
int main()
{
	scanf("%d",&t);
	lg[1]=0;
	for(int i=2;i<=200009;i++)lg[i]=lg[i/2]+1;
	while(t--)
	{
		scanf("%d%d%d",&n,&m,&q);
		for(int i=0;i<=m;i++)
		{
			bian[i].x=0;bian[i].y=0;bian[i].z=0;
		}
		for(int i=0;i<=n+1;i++)
		{
			for(int j=0;j<=lg[n];j++)
			{
				st[i][j]=0;
			}
		}
		for(int i=0;i<=n*2-1;i++)
		{
			g[i].clear();
			p[i]=i;
			poi[i]=0;
			d[i]=0;
			for(int j=0;j<=lg[n*2-1];j++)
			f[i][j]=0;
		}
		for(int i=1;i<=m;i++)
		{
			int x,y;
			scanf("%d%d",&x,&y);
			bian[i].x=x;bian[i].y=y;
			bian[i].z=i;
		}
		//读入+初始化(未用memset怕超时) 
		kru();//Kruskal重构树 
		dfs(n*2-1,0);//lca初始化,从根节点2*n-1开始 
		for(int i=1;i<=n-1;i++)
		{
			st[i][1]=poi[lca(i,i+1)];
		}//st表初始化 
		for(int j=2;j<=lg[n];j++)
		{
			for(int i=1;i+(1<<j)-1<=n;i++)
			{
				st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
			}
		}//预处理st表 
		for(int i=1;i<=q;i++)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			int k=lg[r-l+1];
			printf("%d ",max(st[l][k],st[r-(1<<k)+1][k]));//求解 
		}
		printf("\n");
	}
	return 0;
}
2023/1/31 20:15
加载中...