QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#400908 | #5437. Graph Completing | comeintocalm# | WA | 99ms | 199916kb | C++20 | 6.4kb | 2024-04-27 18:05:36 | 2024-04-27 18:05:37 |
Judging History
answer
#include<bits/stdc++.h>
const int p = 998244353;
typedef long long LL;
using namespace std;
const int mod = p;
const int N = 5e3+7;
template<int mod>
struct ModInt {
#define T (*this)
int x;
ModInt() : x(0) {}
ModInt(int y) : x(y >= 0 ? y : y + mod) {}
ModInt(LL y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
inline int inc(const int &v) {
return v >= mod ? v - mod : v;
}
inline int dec(const int &v) {
return v < 0 ? v + mod : v;
}
inline ModInt &operator+=(const ModInt &p) {
x = inc(x + p.x);
return T;
}
inline ModInt &operator-=(const ModInt &p) {
x = dec(x - p.x);
return T;
}
inline ModInt &operator*=(const ModInt &p) {
x = (int)((LL)x * p.x % mod);
return T;
}
inline ModInt inverse() const {
int a = x, b = mod, u = 1, v = 0, t;
while (b > 0)t = a / b, swap(a -= t * b, b), swap(u -= t * v, v);
return u;
}
inline ModInt &operator/=(const ModInt &p) {
T *= p.inverse();
return T;
}
inline ModInt operator-() const {
return -x;
}
inline friend ModInt operator+(const ModInt &lhs, const ModInt &rhs) {
return ModInt(lhs) += rhs;
}
inline friend ModInt operator-(const ModInt &lhs, const ModInt &rhs) {
return ModInt(lhs) -= rhs;
}
inline friend ModInt operator*(const ModInt &lhs, const ModInt &rhs) {
return ModInt(lhs) *= rhs;
}
inline friend ModInt operator/(const ModInt &lhs, const ModInt &rhs) {
return ModInt(lhs) /= rhs;
}
inline bool operator==(const ModInt &p) const {
return x == p.x;
}
inline bool operator!=(const ModInt &p) const {
return x != p.x;
}
ModInt qpow(LL n) const {
ModInt ret(1), mul(x);
while (n > 0) {
if (n & 1)ret *= mul;
mul *= mul, n >>= 1;
}
return ret;
}
inline friend ostream &operator<<(ostream &os, const ModInt &p) {
return os << p.x;
}
inline friend istream &operator>>(istream &is, ModInt &a) {
LL t;
is >> t, a = ModInt<mod>(t);
return is;
}
static int get_mod() {
return mod;
}
#undef T
};
using Z = ModInt<mod>;
#define pb push_back
int n, m;
std::vector<int> G[N];
Z f[N][N], pw2[N*N];
int Num1[N], siz[N], siz2[N];
namespace tarj {
struct edge {
int next, to;
} e[N << 2];
int ecnt, ehead[N];
int dfn_tot, bel_tot;
int dfn[N], low[N], bel[N], dep[N];
bool vis[N], bridge[N];
int n, m;
inline void AddEdge(const int u, const int v) {
e[++ecnt] = {ehead[u], v}, ehead[u] = ecnt;
e[++ecnt] = {ehead[v], u}, ehead[v] = ecnt;
}
void init() {
ecnt = 1;
dfn_tot = bel_tot = 0;
memset(ehead, 0, sizeof(int) * (n + 1));
memset(dfn, 0, sizeof(int) * (n + 1));
memset(bel, 0, sizeof(int) * (n + 1));
memset(bridge, false, sizeof(bool) * (m + 1));
}
void dfs(const int u, const int pre = -1) {
dfn[u] = low[u] = ++dfn_tot;
for (int i = ehead[u]; i; i = e[i].next) {
int v = e[i].to;
if (dfn[v] == 0) {
dep[v] = dep[u] + 1;
dfs(v, i);
low[u] = std::min(low[u], low[v]);
// printf("dbg %d %d %d %d\n", u, v, low[v], dfn[u]);
if (low[v] > dfn[u]) {
bridge[i / 2] = true;
}
} else if (i != (pre^1)) {
low[u] = std::min(low[u], dfn[v]);
}
}
}
void Shrink(const int u) {
bel[u] = bel_tot;
// printf("bel %d\n", bel_tot);
++siz2[bel_tot];
for (int i = ehead[u]; i; i = e[i].next) {
auto v = e[i].to;
if (!bridge[i / 2]) {
++Num1[bel_tot];
}
if (bel[v] == 0 && !bridge[i / 2]) {
Shrink(v);
}
}
}
void Tarjan() {
dep[1] = 1;
dfs(1);
for (int i = 1; i <= n; ++i) {
if (bel[i] == 0 && dfn[i] != 0) {
++bel_tot;
Shrink(i);
Num1[bel_tot] /= 2;
}
}
for (int u = 1; u <= n; ++u) {
for (int i = ehead[u]; i; i = e[i].next) {
if (bridge[i / 2]) {
int v = e[i].to;
G[bel[u]].emplace_back(bel[v]);
}
}
}
}
}
// number of edges of Node i, tree siz u, orginal siz u
/*
unordered_map<int, bool> vis[N];
void dfs(int u, int fa) {
cout << "NOW::" << u << " Num1[u]: " << Num1[u] << " siz2: " << siz2[u] << "\n";
f[u][1] = pw2[(siz2[u])*(siz2[u]-1)/2-Num1[u]];
siz[u] = 1;
for(auto v : G[u]) if(v != fa) {
dfs(v, u);
siz[u] += siz[v];
siz2[u] += siz2[v];
for(int i = siz[u]; i >= 1; i--) {
for(int j = 1; j <= min(i, siz[v]); j++) {
/// if(connected (i, j)) i + j - 1
/// else i + j
Z u1 = f[u][i - j + 1], u0 = f[u][i - j], v1 = f[v][j + 1], v0 = f[v][j];
if(u == 1 && i == 2) cout << "j::"<<j<< " " << u1 << " " << u0 << " " << v1 << " " << v0 << " " << "\n";
f[u][i] += u0 * v0;
f[u][i] += u1 * v0 * (Z(siz2[u] - siz2[v]) * siz2[v] - 1);
f[u][i] += u0 * v1 * (Z(siz2[u] - siz2[v]) * siz2[v] - 1);
}
}
}
}
*/
void dfs(int u, int fa) {
f[u][1] = pw2[(siz2[u])*(siz2[u]-1)/2-Num1[u]];
siz[u] = 1;
for(auto v : G[u]) if(v != fa) {
dfs(v, u);
siz[u] += siz[v];
siz2[u] += siz2[v];
vector<Z> g(n + 5);
for(int i = 1; i <= siz[u] - siz[v]; i++) {
for(int j = 1; j <= siz[v]; j++) {
g[i + j - 1] += f[u][i] * f[v][j] * Z(pw2[(siz2[u] - siz2[v]) * siz2[v] - 1] - 1);
g[i + j] += f[u][i] * f[v][j];
}
}
for(int i = 1; i <= siz[u]; i++) f[u][i] = g[i];
}
}
void init() {
pw2[0] = 1;
for(int i = 1; i <= 25000000; i++) pw2[i] = pw2[i - 1] * 2;
}
Z iep(Z x) {
if(x.x & 1) return Z(998244352);
return Z(1);
}
Z fac[N], ifac[N];
const int U = 5e3;
Z binom(Z n, Z m) {
if(!m.x) return 1;
if(!n.x) return 0;
return fac[n.x] * ifac[m.x] * ifac[(n - m).x];
}
int main() {
cin >> n >> m;
init();
fac[0] = 1;
for(int i = 1; i <= U; i++) fac[i] = fac[i - 1] * i;
ifac[U] = fac[U].inverse();
for(int i = U - 1; i >= 1; i--) ifac[i] = ifac[i + 1] * (i + 1);
ifac[0] = 1;
tarj::n = n, tarj::m = m;
tarj::init();
for(int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
tarj::AddEdge(u, v);
}
tarj::Tarjan();
dfs(1, 1);
//cout << Num1[1] << "FUCK\n";
Z ans(0);
for(int i = 1; i <= n; i++) {
ans = ans + binom(i, 1) * iep(i - 1) * f[1][i];
}
//for(int i = 1; i <= n; i++) cout << f[1][i] << " " << "\n";
cout << ans << "\n";
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 97ms
memory: 199616kb
input:
3 2 1 2 2 3
output:
1
result:
ok 1 number(s): "1"
Test #2:
score: 0
Accepted
time: 96ms
memory: 199668kb
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: 99ms
memory: 199916kb
input:
2 1 1 2
output:
998244351
result:
wrong answer 1st numbers differ - expected: '0', found: '998244351'