蒟蒻求调
查看原帖
蒟蒻求调
275822
langligelang楼主2023/2/14 22:42

35pts,除了re都有

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn = 5e5 + 10;
const int maxm = 1e6 + 10;
const int mod = 1e9 + 7;
int n, m;

#define gc getchar()
int rd(){
	int x = 0; char ch = gc;
	for (; !isdigit(ch); ch = gc) ;
	for (; isdigit(ch); ch = gc) x = x*10 + ch - '0';
	return x;
}

struct graph{
	int h[maxn], rep = 1;
	struct edge { int to, nx; }e[2 * maxm];
	void ad(int u, int v){e[++rep] = {v, h[u]}, h[u] = rep;}
}g1, g2;
#define to e[i].to

int cnte[maxn], cntp[maxn];

int df[maxn], lw[maxn], tim = 0;
int scc[maxn], cnt = 0;
struct stk{
	int ST[maxn],dir = 0;
	void push(int x) {ST[dir] = x; dir++;}
	void pop() { dir--, ST[dir] = 0;}
	int top() {return ST[dir-1];}
}st;

void tarjan(int x, int f){
	df[x] = lw[x] = ++tim; st.push(x);
	for (int i = g1.h[x]; i; i = g1.e[i].nx){
		if(df[g1.to] == 0){
			tarjan(g1.to, x); lw[x] = min(lw[g1.to], lw[x]);
		}else if(g1.to != f) lw[x] = min(lw[g1.to], df[x]);
	}
	if(lw[x] == df[x]) {
		++cnt;
		for (int flg = 0; ; st.pop()){
			if(flg) break;
			if(st.top() == x) flg = 1;
			scc[st.top()] = cnt; 
			cntp[cnt] ++;
		}
	}
}

int s[maxn];
void wk_s(int x, int f){
	s[x] = cnte[x];
	for (int i = g2.h[x]; i; i = g2.e[i].nx){
		if(g2.to == f) continue;
		wk_s(g2.to, x);
		s[x] += s[g2.to] + 1;
	}
}

int mypow(int x){
	int tot = 0;
	while(x >= 30) tot = (tot + (1<<30))%mod, x -= 30;
	tot = (tot + (1<<x))%mod;
	return tot;
}

int ans = 0;
int dp[maxn][2], vis[maxn];
void wk_dp(int x, int f){
	if(vis[x]) return ; vis[x] = 1;
	dp[x][0] = mypow(cnte[x]);
	dp[x][1] = (mypow(cnte[x] + cntp[x]) - dp[x][0] +mod)%mod;
	for (int i = g2.h[x]; i; i = g2.e[i].nx){
		if(g2.to == f) continue;
		wk_dp(g2.to, x);
		
		dp[x][1] = dp[x][0] * dp[g2.to][1] + dp[x][1] * (dp[g2.to][1] + 2*dp[g2.to][0]);  
		dp[x][0] *= 2*dp[g2.to][0];
		
		dp[x][0] %= mod;
		dp[x][1] %= mod;
	}
	if(x == 1) ans += dp[x][1];
	else ans += ( dp[x][1] * mypow(s[1] - s[x] - 1) )%mod;
	ans %= mod;
}


signed main(){
	cin >> n >> m;
	for (int i = 1, u, v; i <= m; i++){
		u = rd(), v = rd();
		g1.ad(u, v), g1.ad(v, u); 
	} 
	
	tarjan(1,-1);
	
	for (int j = 1; j <= n; j++){
		for (int i = g1.h[j]; i; i = g1.e[i].nx){
			if(scc[j] == scc[g1.to]) cnte[scc[j]]++;
			else{
				g2.ad(scc[j], scc[g1.to]);
			}
		}
	}
	
	for (int i = 1; i <= cnt; i ++) cnte[i] = cnte[i]/2;
	
	wk_s(1,-1);
	wk_dp(1,-1);
	
	cout << ans;
	return 0;
}
2023/2/14 22:42
加载中...