其他分享
首页 > 其他分享> > [WC2018]州区划分

[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 List{int 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;
}

标签:州区,return,int,rep,划分,MAXN,now,WC2018,dp
来源: https://www.cnblogs.com/gdc-destinies/p/11252752.html