QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#773167#7932. AND-OR closureucup-team2172WA 1ms7828kbC++142.6kb2024-11-23 02:40:472024-11-23 02:40:47

Judging History

你现在查看的是最新测评结果

  • [2024-11-23 02:40:47]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:7828kb
  • [2024-11-23 02:40:47]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

const int n = 40;
const long long FULL = (1ll << n) - 1;
const int maxn = 45;
const int maxm = 2e5 + 5;

int m;
long long a[maxm];

int clk = 0, top = 0, tot = 0;
int low[maxn], dfn[maxn], stk[maxn], ins[maxn], col[maxn];
vector<int> g[maxn];
inline void tarjan(int u) {
	low[u] = dfn[u] = clk++;
	ins[stk[++top] = u] = true;
	for (auto v: g[u]) {
		if (!~dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
		else if (ins[v]) low[u] = min(low[u], dfn[v]);
	}
	if (low[u] == dfn[u]) {
		for (int v = stk[top]; ; v = stk[--top]) {
			col[v] = tot;
			ins[v] = false;
			if (v == u) break;
		}
		++tot;
	}
}

int ed[maxn][maxn];
long long to[maxn], from[maxn];
long long h[1 << n / 2];

long long OCC = 0, AND;

inline void scc() {
	memset(dfn, -1, sizeof(dfn));
	for (int x = 0; x < n; ++x) if ((OCC >> x & 1) && !~dfn[x]) tarjan(x);
	for (int x = 0; x < n; ++x) for (auto y: g[x]) if (col[x] != col[y]) ed[col[x]][col[y]] = 1, printf("edge %d %d\n", col[x], col[y]);
	for (int k = 0; k < tot; ++k) for (int i = 0; i < tot; ++i) for (int j = 0; j < tot; ++j)
		if (ed[i][k] && ed[k][j]) ed[i][j] = 1;
	for (int i = 0; i < tot; ++i) for (int j = 0; j < tot; ++j) if (ed[i][j])
		to[tot - i - 1] |= 1ll << (tot - j - 1), from[tot - j - 1] |= 1ll << (tot - i - 1);
}

int f[1 << n / 2], r[1 << n / 2];

int main(){
	scanf("%d", &m);
	OCC = 0;
	AND = FULL;
	for (int i = 0; i < m; ++i) scanf("%lld", a + i), OCC |= a[i], AND &= a[i];
	
	for (int x = 0; x < n; ++x) if (OCC >> x & 1){
		long long sum = FULL;
		for (int i = 0; i < m; ++i) if (a[i] >> x & 1) sum &= a[i];
		for (int y = 0; y < n; ++y) if (sum >> y & 1) g[x].push_back(y);
	}
	
	scc();
	
	const int half = tot / 2;
	const int left = (1 << half) - 1;
	
	for (int S = 0; S < (1 << half); ++S) {
		f[S] = 1;
		for (int i = 0; i < half; ++i) if (S >> i & 1) f[S] &= ((to[i] & left & S) == (to[i] & left));
	}
	
	for (int S = 0; S < (1 << tot - half); ++S) {
		r[S] = 1;
		for (int i = 0; i < tot - half; ++i) if (S >> i & 1) r[S] &= (((to[i + half] >> half) & S) == (to[i + half] >> half));
	}
	
	for (int i = 0; i < half; ++i) for (int S = 0; S < (1 << half); ++S) if (S >> i & 1) f[S] += f[S ^ (1 << i)];
	
	for (int S = 1; S < (1 << tot - half); ++S) for (int i = 0; i < tot - half; ++i)
		if (S >> i & 1) h[S] = h[S ^ (1 << i)] | from[i + half]; 
	
	
	long long ans = 0;
	for (int S = 0; S < (1 << tot - half); ++S) if (r[S]){
		long long ban = h[(1 << tot - half) - 1 - S] & left;
		ans += f[(1 << half) - 1 - ban];
	}
	
	if (AND) --ans;
	
	printf("%lld\n", ans);
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 1ms
memory: 7828kb

input:

4
0 1 3 5

output:

edge 1 0
edge 2 0
5

result:

wrong output format Expected integer, but "edge" found