蒟蒻求助点仙人掌QWQ
  • 板块CF231E Cactus
  • 楼主MCAdam
  • 当前回复1
  • 已保存回复1
  • 发布时间2020/8/20 08:18
  • 上次更新2023/11/6 19:52:55
查看原帖
蒟蒻求助点仙人掌QWQ
81238
MCAdam楼主2020/8/20 08:18

边双联通缩点后倍增,莫名TLE

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#define ll long long
using namespace std;
const int N=1e5+10,M=2e5+10,mod=1e9+7;
int cnt,dcc;
int dfn[N],low[N],bridge[M],col[N],size[N],f[N][22],g[N][22],dep[N];
struct graph
{
	int tot;
	int fir[N],to[M],nxt[M];
	graph(){ tot=1; memset(fir,0,sizeof(fir)); }
	inline void add(int x,int y)
	{
		to[++tot]=y; nxt[tot]=fir[x]; fir[x]=tot;
		to[++tot]=x; nxt[tot]=fir[y]; fir[y]=tot;
	}
}e1,e2;
inline void tarjan(int p,int le)
{
	dfn[p]=low[p]=++cnt;
	for(int i=e1.fir[p];i;i=e1.nxt[i])
	{
		int q=e1.to[i];
		if(!dfn[q])
		{
			tarjan(q,i);
			low[p]=min(low[p],low[q]);
			if(low[q]>dfn[p]) bridge[i]=bridge[i^1]=1;
		}
		else if(i!=(le^1)) low[p]=min(low[p],dfn[q]);
	}
}
inline void dfs1(int p)
{
	col[p]=dcc;
	for(int i=e1.fir[p];i;i=e1.nxt[i])
		if(!col[e1.to[i]]&&!bridge[i]) dfs1(e1.to[i]);
	size[dcc]++;
}
inline void dfs2(int p)
{
	for(int i=e2.fir[p];i;i=e2.nxt[i])
	{
		int q=e2.to[i];
		if(q==f[p][0]) continue;
		dep[q]=dep[p]+1;
		f[q][0]=p,g[q][0]=(size[q]>1);
		for(int j=1;j<=log2(dep[q]);j++)
			f[q][j]=f[f[q][j-1]][j-1],g[q][j]=g[q][j-1]+g[f[q][j-1]][j-1];
		dfs2(q);
	}
}
inline int get_lca(int x,int y)
{
	int ans=0;
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=log2(dep[x]);i>=0;i--)
		if(dep[f[x][i]]>=dep[y]) ans+=g[x][i],x=f[x][i];
	if(x==y) return ans+g[y][0];
	for(int i=log2(dep[x]);i>=0;i--)
	{
		if(f[x][i]==f[y][i]) continue;
		ans+=g[x][i]+g[y][i];
		x=f[x][i],y=f[y][i];
	}
	return ans+g[x][0]+g[y][0]+g[f[x][0]][0];
}
inline int power(int a,int b)
{
	int res=1;
	while(b)
	{
		if(b&1) res=(ll)res*a%mod;
		b>>=1;
		a=(ll)a*a%mod;
	}
	return res;
}
int main()
{
	int n,m,T,a,b;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&a,&b);
		e1.add(a,b);
	}
	for(int i=1;i<=n;i++)
		if(!dfn[i]) tarjan(i,-1);
	for(int i=1;i<=n;i++)
		if(!col[i]) dcc++,dfs1(i);
	for(int p=1;p<=n;p++)
	{
		for(int i=e1.fir[p];i;i=e1.nxt[i])
		{
			int q=e1.to[i];
			if(col[p]==col[q]) continue;
			e2.add(col[p],col[q]);
		}
	}
	dep[1]=1,g[1][0]=(size[1]>1);
	dfs2(1);
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d",&a,&b);
		printf("%d\n",power(2,get_lca(col[a],col[b])));
	}
	return 0;
}
2020/8/20 08:18
加载中...