Submission #781152

#TimeUsernameProblemLanguageResultExecution timeMemory
781152definitelynotmeeAmusement Park (CEOI19_amusementpark)C++17
63 / 100
3029 ms10688 KiB
#include<bits/stdc++.h>
#define ff first
#define ss second
#define all(x) x.begin(), x.end()
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
template<typename T>
using matrix = vector<vector<T>>;
const int MOD = 998244353;

struct gc{
    int id, sign;
};

int main(){
    cin.tie(0)->sync_with_stdio(0);

    int n, m;
    cin >> n >> m;

    vector<int> adj(n);

    for(int i = 0; i < m; i++){
        int a, b;
        cin >> a >> b;
        a--, b--;
        adj[a]+=1<<b;
    }

    vector<int> incomp(1<<n);

    for(int i = 0; i < (1<<n); i++){
        int ok = 0;
        for(int j = 0; j < n; j++){
            if((1<<j)&i){
                ok|=adj[j];
            }
        }
        
        incomp[i] = !bool(ok&i);
        // cerr << bitset<4>(ok) << ' ' << bitset<4>(i) << "->" << incomp[i] << '\n';
    }

    vector<int> sum(1<<n), dp(1<<n);

    dp[0] = 1;
    
    matrix<gc> gray(n);
    gray[0] = {{0,1}};
    for(int i = 1; i < n; i++){
        gray[i] = gray[i-1];
        gray[i].push_back({i,1});
        for(int j = gray[i-1].size()-1; j >= 0; j--){
            gc cur = gray[i-1][j];
            cur.sign*=-1;
            gray[i].push_back(cur);

        }
    }

    // for(auto i : gray.back())
    //     cout << bitset<4>(i.mask) << ' ' << i.id << ' ' << i.sign << '\n';



    for(int mask = 1; mask < (1<<n); mask++){
        vector<int> cur;
        for(int j = 0 ; j < n; j++){
            if(mask&(1<<j))
                cur.push_back(j);
        }
        int p = -1, sub = 0;
        ll cursum = 0;
        for(gc i : gray[__builtin_popcount(mask)-1]){
            const int id = cur[i.id];
            
            sub+=(1<<id)*i.sign;
            cursum+=__builtin_popcount(adj[id]&mask)*i.sign;
            p*=-1;
            // cerr << bitset<4>(mask) << "->" << bitset<4>(sub) << '\n';

            const int comp = mask^sub;
            dp[mask]+=p*dp[comp]*incomp[sub];
            sum[mask]+=p*(cursum*dp[comp]+sum[comp])*incomp[sub]%MOD;
            dp[mask]%=MOD;
            sum[mask]%=MOD;
        }
    }
    if(sum[(1<<n)-1] < 0)
        sum[(1<<n)-1]+=MOD;

    cout << sum[(1<<n)-1] << '\n';

}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...