QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#448481 | #6874. Leshphon | Romeo | AC ✓ | 571ms | 3860kb | C++17 | 2.7kb | 2024-06-19 17:37:57 | 2024-06-19 17:37:58 |
Judging History
answer
#include <iostream>
#include <algorithm>
#include <cstring>
typedef long long ll;
const ll N = 50;
const ll M = 2e3;
inline ll read() {ll x; return scanf("%lld", &x), x;}
ll n, m;
ll bit[2][N + 5];
#define lowbit __builtin_ctzll
inline bool check(ll type)
{
static ll s, q[N + 5], l, r;
s = (1ll << n) - 1, l = 1, r = 0;
q[ ++ r] = 0;
while (l <= r)
{
ll u = q[l ++ ], t = bit[type][u] & s;
while (t)
{
ll v = q[ ++ r] = lowbit(t);
s ^= 1ll << v, t ^= 1ll << v;
}
}
return !s;
}
inline bool lets_check_check() {return check(0) && check(1);}
ll bang[N + 5];
ll f[N + 5], g[N + 5];
ll dfn[N + 5], low[N + 5], tim;
ll stack[N + 5], top;
bool in_stack[N + 5];
ll scc;
void tarjan(ll u)
{
dfn[u] = low[u] = ++ tim;
stack[ ++ top] = u;
in_stack[u] = 1;
for (ll v = 0; v < n; v ++ )
{
if (bit[0][u] >> v & 1 ^ 1) continue;
if (!dfn[v]) tarjan(v), low[u] = std :: min(low[u], low[v]), f[v] = u;
else if (in_stack[v]) if (low[u] > dfn[v]) low[u] = dfn[v], g[u] = v;
}
if (dfn[u] == low[u])
{
scc ++ ;
do in_stack[stack[top]] = 0; while (stack[top -- ] != u) ;
}
}
ll res;
void dfs(ll dep)
{
if (dep == 3) return res -= lets_check_check(), void();
ll ip[N + 5];
std :: memset(ip, 0, sizeof ip);
std :: memset(f, -1, sizeof f), std :: memset(g, -1, sizeof g);
scc = tim = 0;
std :: memset(dfn, 0, sizeof dfn);
for (ll i = 0; i < n; i ++ ) if (!dfn[i]) tarjan(i);
if (scc > 1) return ;
for (ll i = 0; i < n; i ++ )
{
if (~f[i]) ip[f[i]] |= 1ll << i;
if (~g[i]) ip[i] |= 1ll << g[i];
}
ll cnt = 0;
for (ll i = 0; i < n; i ++ )
for (ll j = 0; j < n; j ++ )
{
if (bit[0][i] >> j & 1 ^ 1) continue;
if (bang[i] >> j & 1) {if (ip[i] >> j & 1) ip[i] ^= 1ll << j; continue;}
if (ip[i] >> j & 1) continue;
cnt ++ ;
}
if (dep == 0) res -= (ll)cnt * (cnt - 1) * (cnt - 2) / 6;
if (dep == 1) res -= cnt * (cnt - 1) / 2;
if (dep == 2) res -= cnt;
for (ll i = 0; i < n; i ++ )
{
for (ll j = 0; j < n; j ++ )
{
if (ip[i] >> j & 1 ^ 1) continue;
bit[0][i] ^= 1ll << j, bit[1][j] ^= 1ll << i;
dfs(dep + 1);
bit[0][i] ^= 1ll << j, bit[1][j] ^= 1ll << i;
bang[i] ^= 1ll << j;
}
}
for (ll i = 0; i < n; i ++ )
{
for (ll j = 0; j < n; j ++ )
{
if (ip[i] >> j & 1 ^ 1) continue;
bang[i] ^= 1ll << j;
}
}
}
int main()
{
ll T = read();
while (T -- )
{
n = read(), m = read();
std :: memset(bit, 0, sizeof bit);
res = (ll)m * (m - 1) * (m - 2) / 6;
while (m -- )
{
ll u = read() - 1, v = read() - 1;
bit[0][u] |= 1ll << v, bit[1][v] |= 1ll << u;
}
dfs(0);
printf("%lld\n", res);
}
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 571ms
memory: 3860kb
input:
10 50 145 1 6 1 33 1 38 2 11 2 29 2 36 2 42 3 20 3 35 3 36 4 39 5 39 6 10 6 23 6 27 6 34 6 39 6 45 6 47 7 24 7 37 8 14 8 47 9 3 9 40 10 5 10 12 10 25 11 14 11 18 12 13 12 44 13 38 14 38 15 4 15 29 15 31 15 36 15 44 16 17 16 35 17 18 17 50 18 3 18 19 18 20 18 27 19 31 20 22 20 31 21 8 21 22 21 27 21 ...
output:
159936 126858 722 0 833992 2756 1263249 6657 5531904 38194324
result:
ok 10 lines