[WC2018]州区划分
Posted gdc-destinies
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[WC2018]州区划分相关的知识,希望对你有一定的参考价值。
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i, s, t) for(int i = s, __ = t; i <= __; ++i)
#define dwn(i, s, t) for(int i = s, __ = t; i >= __; --i)
const int INF = 2147483647;
const int MAXN = 31;
const int MAXM = 100 + 2500000;
const int MOD = 998244353;
using namespace std;
inline int read(int x = 0, int f = 1)
char ch = getchar();
for(; !isdigit(ch); ch = getchar())if(ch == '-')f = -1;
for(; isdigit(ch); ch = getchar())x = ch - '0' + x * 10;
return x * f;
inline void write(int x)
if(x >= 10)write(x / 10); putchar(x % 10 + '0'); return ;
inline int add(int x, int y)x += y; return x >= MOD ? x - MOD : x;
inline int sub(int x, int y)x -= y; return x < 0 ? x + MOD : x;
inline void inc(int &x, int y)x += y, x -= x >= MOD ? MOD : 0; return ;
inline void dec(int &x, int y)x -= y, x += x < 0 ? MOD : 0; return ;
inline int mul(int x, int y)return (ll)x * y % MOD;
inline int fpow(int x, int y, int tmp = 1)
while(y)if(y & 1)tmp = mul(tmp, x); x = mul(x, x), y >>= 1; return tmp;
inline int inv(int x)return fpow(x, MOD - 2);
inline int die(int x, int y)return (ll)x * inv(y) % MOD;
int n, m, p, lim, num = -1, fs[MAXN], q[MAXN];
struct Listint u, v;
void get()u = read(), v = read(); return ;
Edge[MAXN * MAXN >> 1];
int f[MAXN], can[MAXM], vis[MAXN], du[MAXN];
int s[MAXN][MAXM], dp[MAXN][MAXM], bc[MAXM], sum[MAXM];
int find(int x)return f[x] == x ? x : find(f[x]);
int check(int now, int rec = 0)
rep(i, 1, n)vis[i] = (now >> i - 1) & 1;
rep(i, 1, n)du[i] = 0, f[i] = i, rec = vis[i] ? i : rec;
if(bc[now] != 1)rep(i, 1, n)inc(sum[now], vis[i] * q[i]);
rep(i, 1, m)if(vis[Edge[i].u] && vis[Edge[i].v])
du[Edge[i].u]++, du[Edge[i].v]++;
f[find(Edge[i].u)] = f[find(Edge[i].v)];
rep(i, 1, n)if(vis[i])
if((find(i) != find(rec)) || (du[i] % 2))return 1;
return 0;
void fmt(int *u, int tag)
for(int i = 1; i < lim; i <<= 1)rep(j, 0, lim)
if(i & j)inc(u[j], ~tag ? u[j - i] : sub(0, u[j - i]));
return ;
void init()
memset(fs, -1, sizeof(fs));
n = read(), m = read(), p = read();
lim = (1 << n) - 1;
rep(i, 1, m)Edge[i].get(); rep(i, 1, n)q[i] = read();
rep(now, 1, lim)bc[now] = bc[now >> 1] + (now & 1);
rep(now, 1, lim)can[now] = check(now);
rep(now, 0, lim)
sum[now] = fpow(sum[now], p);
if(can[now])s[bc[now]][now] = sum[now];
sum[now] = inv(sum[now]);
return ;
void work()
rep(now, 0, lim)dp[1][now] = (bc[now] == 1) * can[now];
rep(i, 1, n)fmt(s[i], 1);
dp[0][0] = 1, fmt(dp[0], 1); fmt(dp[1], 1);
rep(i, 2, n)
rep(j, 0, i - 1)rep(now, 0, lim)
inc(dp[i][now], mul(dp[j][now], s[i - j][now]));
fmt(dp[i], -1);
rep(now, 0, lim)if(bc[now] != i)dp[i][now] = 0;
else dp[i][now] = mul(dp[i][now], sum[now]);
if(i != n)fmt(dp[i], 1);
write(dp[n][lim]); return ;
int main()
init(); work(); return 0;
以上是关于[WC2018]州区划分的主要内容,如果未能解决你的问题,请参考以下文章