社区讨论

MLE 求助

P8867[NOIP2022] 建造军营参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lp0x20no
此快照首次捕获于
2023/11/16 16:15
2 年前
此快照最后确认于
2023/11/16 16:25
2 年前
查看原帖
数组只开了 61 MB, MLE on #17 #18 #19 #20,#37 #38 #39 #40,分别是两组数据的最后四个点
CPP
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e5 + 10, M = 1e6 + 10, mod = 1e9 + 7, INF = 0x3f3f3f3f;
int n, m, tot = 1, k, cnt, dcc, top;
int head[N], ver[M * 2], nxt[M * 2], low[N], dfn[N], in[N], s[N];
int frm[N], v[N], e[N], x[N], y[N], bs[N];
bool bridge[M * 2], vis[N], vis2[M * 2];
ll f[N][2], ans;

void add(int x, int y) {
	ver[++tot] = y;
	nxt[tot] = head[x];
	head[x] = tot;
}

void tarjan(int x, int fa) {
	low[x] = dfn[x] = ++cnt;
	s[++top] = x; in[x] = 1;
	for(int i = head[x]; i; i = nxt[i]) {
		int y = ver[i];
		if(y == fa) continue;
		if(!dfn[y]) {
			tarjan(y, x);
			low[x] = min(low[x], low[y]);
			if(dfn[x] < low[y]) bridge[i] = bridge[i ^ 1] = 1;
		}
		else if(in[y]) low[x] = min(low[x], dfn[y]);
	}
	if(dfn[x] == low[x]) {
		dcc++; int u;
		do {
			u = s[top--];
			in[u] = 0; frm[u] = dcc;
			v[dcc]++;
		}while(x != u);
	}
}

void dfs1(int x, int rt) {
	vis[x] = 1;
	for(int i = head[x]; i; i = nxt[i]) {
		int y = ver[i];
		if(bridge[i]) continue;
		if(!vis2[i]) {
			e[rt]++;
			vis2[i] = vis2[i ^ 1] = 1;
		}
		if(vis[y]) continue;
		dfs1(y, rt);
	}
}

ll ksm(ll a, int b) {
	ll res = 1;
	for(; b; b >>= 1) {
		if(b & 1) res = (res * a) % mod;
		a = (a * a) % mod;
	}
	return res;
}

void dfs2(int x, int fa) {
	bs[x] = e[x];
	for(int i = head[x]; i; i = nxt[i]) {
		int y = ver[i];
		if(y == fa) continue;
		dfs2(y, x);
		bs[x] += bs[y] + 1;
	}
}

void dfs3(int x, int fa) {
	for(int i = head[x]; i; i = nxt[i]) {
		int y = ver[i];
		if(y == fa) continue;
		dfs3(y, x);
		f[x][1] = (f[x][0] * f[y][1] % mod + f[x][1] * (2 * f[y][0] %mod + f[y][1]) % mod) % mod;
		f[x][0] = (f[x][0] * f[y][0] % mod * 2) % mod;
	}
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= m; i++) {
		scanf("%d%d", &x[i], &y[i]);
		add(x[i], y[i]); add(y[i], x[i]);
	}
	tarjan(1, 0);
	for(int i = 1; i <= n; i++) {
		if(vis[i]) continue;
		dfs1(i, frm[i]);
	}
	tot = 0;
	memset(head, 0, sizeof(head));
	for(int i = 1; i <= m; i++) {
		int fx = frm[x[i]], fy = frm[y[i]];
		if(fx == fy) continue;
		add(fx, fy); add(fy, fx);
	}
	for(int i = 1; i <= dcc; i++) {
		f[i][0] = ksm(2LL, e[i]);
		f[i][1] = (ksm(2LL, e[i] + v[i]) - f[i][0] + mod) % mod;
	}
	dfs2(1, 0);
	dfs3(1, 0);
	ans = f[1][1];
	for(int i = 2; i <= dcc; i++) 
		(ans += f[i][1] * ksm(2LL, bs[1] - bs[i] - 1) % mod) %= mod;
	printf("%lld", ans);
	return 0; 
}

回复

0 条回复,欢迎继续交流。

正在加载回复...