Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #define pb emplace_back
- #define AI(i) begin(i), end(i)
- template<class T>
- bool chmax(T &val, T nv) {
- return val < nv ? (val = nv, true) : false;
- }
- template<class T>
- bool chmin(T &val, T nv) {
- return nv < val ? (val = nv, true) : false;
- }
- using namespace std;
- using ll = long long;
- #ifdef KEV
- #define DE(args...) kout("[ " + string(#args) + " ] = ", args)
- void debug(auto L, auto R) { while (L < R) cerr << *L << " \n"[L+1==R], ++L; }
- void kout(){ cerr << endl; }
- template<class T1, class ...T2> void kout(T1 a, T2 ...e) { cerr << a << ' ', kout(e...); }
- #else
- #define DE(...) 0
- #define debug(...) 0
- #endif
- // What I should check
- // 1. overflow
- // 2. corner cases
- // Enjoy the problem instead of hurrying to AC
- // Good luck !
- const int MAX_N = 20, p = 998244353;
- void add(int &a, int b) { a += b - p, a += (a>>31) & p; }
- int n, m, a[MAX_N][MAX_N], pos[MAX_N][MAX_N];
- int A[1<<MAX_N], B[1<<MAX_N];
- int32_t main() {
- ios_base::sync_with_stdio(0), cin.tie(0);
- cin >> m >> n;
- for (int i = 0;i < m;++i)
- for (int j = 0;j < n;++j) {
- cin >> a[i][j], --a[i][j];
- pos[i][ a[i][j] ] = 1<<j;
- }
- auto dp = A, tmp = B;
- dp[0] = 1;
- for (int d = 0;d < m;++d) {
- memset(tmp, 0, sizeof(A));
- for (int i = 0;i + 1 < n;++i)
- for (int s = 0;s < 1<<n;++s) if (dp[s])
- if ((s & (0b11 << i)) == 0) {
- add(dp[s | (0b11<<i)], dp[s]);
- }
- if (d == m-1)
- return cout << dp[(1<<n)-1] << '\n', 0;
- for (int s = 0;s < 1<<n;++s) if (dp[s]) {
- int mask = 0;
- for (int i = 0;i < n;++i) if ( (~s>>i&1) )
- mask |= pos[d+1][a[d][i]];
- tmp[mask] = dp[s];
- }
- swap(dp, tmp);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement