QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#618052 | #5437. Graph Completing | Cipherxzc# | WA | 90ms | 202864kb | C++23 | 3.7kb | 2024-10-06 18:20:30 | 2024-10-06 18:20:30 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int N = 5005, mod = 998244353;
int n, m, siz[N];
vector<int> e[N];
LL fac[N], ifac[N], f[N][N], pw[N * N];
namespace Tarjan { // 强连通分量
int dfn[N], low[N], tot;
int id[N], num;
bool ins[N];
stack<int> st;
vector<int> e[N];
void init() {
for (int i = 1; i <= n; i++) {
dfn[i] = 0;
ins[i] = false;
}
tot = num = 0;
}
void tarjan(int p, int fa) {
low[p] = dfn[p] = ++tot;
st.push(p);
ins[p] = true;
for (int q : e[p]) {
if (q == fa){
continue;
}
if (!dfn[q]) {
tarjan(q, p);
low[p] = min(low[p], low[q]);
} else if (ins[q]) {
low[p] = min(low[p], low[q]);
}
}
if (dfn[p] == low[p]) {
num++;
int q = 0;
while (q != p) {
q = st.top();
st.pop();
ins[q] = false;
id[q] = num;
}
}
}
void work() { // tarjan缩点的结果符合拓扑序
for (int i = 1; i <= n; i++) {
if (!dfn[i]) {
tarjan(i, 0);
}
}
}
inline void add(int u, int v){
e[u].push_back(v);
e[v].push_back(u);
}
} // namespace Tarjan
using Tarjan::id;
inline void add(int u, int v){
e[u].push_back(v);
e[v].push_back(u);
}
inline LL qp(LL x, LL y){
LL res = 1;
while (y){
if (y & 1){
res = res * x % mod;
}
y >>= 1;
x = x * x % mod;
}
return res;
}
inline LL inv(LL x){
return qp(x, mod - 2);
}
inline LL C(LL x, LL y){
return fac[x] * ifac[y] % mod * ifac[x - y] % mod;
}
void dfs(int p, int fa){
// cout << p << ' ';
for (int i = 0; i <= siz[p]; i++){
f[p][i] = C(siz[p], i);
// cout << f[p][i] << ' ';
}
// cout << endl;
for (int q : e[p]){
if (q == fa){
continue;
}
dfs(q, p);
siz[p] += siz[q];
for (int i = siz[p]; i >= 0; i--){
LL tmp = 0;
for (int j = 0; j <= min(i, siz[q]); j++){
tmp = (tmp + f[p][i - j] * f[q][j] % mod * pw[(i - j) * j]) % mod; // 打表
}
f[p][i] = tmp;
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
fac[0] = 1;
for (int i = 1; i < N; i++){
fac[i] = fac[i - 1] * i % mod;
}
ifac[N - 1] = inv(fac[N - 1]);
for (int i = N - 2; i >= 0; i--){
ifac[i] = ifac[i + 1] * (i + 1) % mod;
}
pw[0] = 1;
for (int i = 1; i < N * N; i++){
pw[i] = pw[i - 1] * 2 % mod;
}
cin >> n >> m;
for (int i = 1, u, v; i <= m; i++){
cin >> u >> v;
Tarjan::add(u, v);
}
Tarjan::init();
Tarjan::work();
map<int, LL> cnt;
for (int i = 1; i <= n; i++){
siz[id[i]]++;
for (int j : Tarjan::e[i]){
if (id[i] != id[j]){
add(id[i], id[j]);
}else if (i < j){
cnt[id[i]]++;
}
}
}
LL ans = 1;
for (int i = 1; i <= Tarjan::num; i++){
sort(e[i].begin(), e[i].end());
e[i].erase(unique(e[i].begin(), e[i].end()), e[i].end());
LL tmp = siz[i] * (siz[i] - 1) / 2 - cnt[i];
ans = ans * pw[tmp] % mod;
}
dfs(1, 0);
ans = ans * f[1][0] % mod;
cout << ans << endl;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 81ms
memory: 200052kb
input:
3 2 1 2 2 3
output:
1
result:
ok 1 number(s): "1"
Test #2:
score: 0
Accepted
time: 83ms
memory: 199776kb
input:
4 4 1 2 2 3 3 4 4 1
output:
4
result:
ok 1 number(s): "4"
Test #3:
score: -100
Wrong Answer
time: 90ms
memory: 202864kb
input:
2 1 1 2
output:
1
result:
wrong answer 1st numbers differ - expected: '0', found: '1'