我的这份代码时间复杂度理论上应该是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;
}