关于这份代码的常数
查看原帖
关于这份代码的常数
234973
lllhhh楼主2022/12/2 21:10

我的这份代码时间复杂度理论上应该是O(n+m)

但是交到Luogu上评测时 #10~#16 却TLE

请问是因为常数的问题,还是时间复杂度假掉了QAQ

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+5,maxm=1e6+5;
const ll mod=1e9+7;
int n,m,hd[maxn],tot,dfn[maxn],low[maxn],cnt;
int _tot,sc,_hd[maxn],sta[maxn],cur,col[maxn],d[maxn],w[maxn],zc[maxn];
bool in[maxn];
ll P[maxm<<1],dp[maxn][2];
struct node{
	int fro,to,nxt;
};
node e[maxm<<1],g[maxm<<1];
inline int rd(){
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-'){f=-1;}ch=getchar();}
	while (isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
inline void add1(int u,int v){
	e[++tot].to=v;e[tot].fro=u;e[tot].nxt=hd[u];hd[u]=tot;
}
void tarjan(int u,int fa){
	dfn[u]=low[u]=++cnt;
	sta[++cur]=u;in[u]=1;
	for (int i=hd[u];i;i=e[i].nxt){
		int v=e[i].to;
		if (v==fa) continue;
		if (!dfn[v]){
			tarjan(v,u);
			low[u]=min(low[u],low[v]);
		}
		else if (in[v]){
			low[u]=min(low[u],dfn[v]);
		}
	}
	if (dfn[u]==low[u]){
		int v;++sc;
		while (cur>0){
			v=sta[cur--];
			col[v]=sc;
			++d[sc];
			in[v]=0;
			if (v==u) break;
		}
	}
}
inline void add2(int u,int v){
	g[++_tot].to=v;g[_tot].nxt=_hd[u];_hd[u]=_tot;
}
inline ll M(ll x){while (x>=mod){x-=mod;}return x;}
void DP(int u,int fa){
	for (int i=_hd[u];i;i=g[i].nxt){
		int v=g[i].to;
		if (v==fa) continue;
		DP(v,u);
		zc[u]+=zc[v]+1;
	}
	zc[u]+=w[u];
	dp[u][0]=0;dp[u][1]=1;
	for (int i=_hd[u];i;i=g[i].nxt){
		int v=g[i].to;
		if (v==fa) continue;
		dp[u][0]+=M(M(dp[v][0]+dp[v][1])*P[zc[u]-zc[v]-1]);
		dp[u][0]=M(dp[u][0]);
		dp[u][1]*=M(dp[v][0]+dp[v][1]+(P[zc[v]]<<1));
		dp[u][1]=M(dp[u][1]);
	}
	dp[u][1]=M(dp[u][1]*P[d[u]+w[u]]);
	dp[u][1]=M(dp[u][1]-P[zc[u]]+mod-dp[u][0]+mod);
}
void Init(){
	P[0]=1;
	for (int i=1;i<=n+m;++i) P[i]=M(P[i-1]<<1);
}
int main(){
	n=rd();m=rd();
	Init();
	int u,v;
	for (int i=1;i<=m;++i){
		u=rd(),v=rd();
		add1(u,v);add1(v,u);
	}
	tarjan(1,0);
	for (int i=1;i<=tot;i+=2){
		u=e[i].fro,v=e[i].to;
		if (col[u]!=col[v]){
			add2(col[u],col[v]);
			add2(col[v],col[u]);
		}
		else ++w[col[u]];
	}
	DP(1,0);
	ll ans=0;
	for (int i=1;i<=sc;++i){
		ans+=M(dp[i][1]*P[zc[1]-zc[i]]);
		ans=M(ans);
	}
	printf("%lld",ans);
	
	return 0;
}
2022/12/2 21:10
加载中...