18.11.8 考试总结
早上的思路是很接近正解了QAQ
$dp[i][sta]$表示到了第$i$层当前的奇偶状态为$sta$的方案数
那么转移下一层就需要考虑当前边的状态 设置$up, dn$为当前的点连接到的前一层的点的状态
那么他的贡献就有当前的状态并上上一层的状态才能够累加贡献 就这样往后推即可
代码
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll MOD = 998244353; const int STA = (1 << 11) + 5; int m, k; ll ans = 0, dp[2][STA], pre[STA], up[STA], dn[STA]; void init( ) { for(int i = 0; i < (1 << k); i ++) pre[i] = (i & 1) ^ (pre[i >> 1]); } void Moc(ll & a, ll b) { a = (a + b) % MOD; } int read( ) { int t = 1, ans = 0; char x; x = getchar( ); while(x < '0' || x > '9') { if(x == '-') t = -1; x = getchar( ); } while(x >= '0' && x <= '9') { ans = ans * 10 + x - '0'; x = getchar( ); } return ans * t; } int main( ) { freopen("adore.in", "r", stdin); freopen("adore.out", "w", stdout); m = read( ), k = read( ); int s = 0; for(int i = 0; i < k; i ++) { int x; x = read( ); s |= (x << i); } init( ); dp[0][s] = 1; int now = 0; for(int i = 2; i < m - 1; i ++) { now ^= 1; memset(dp[now], 0, sizeof(dp[now])); memset(up, 0, sizeof(up)); memset(dn, 0, sizeof(dn)); for(int u = 0; u < k; u ++) for(int v = 0; v < k; v ++) { int x; x = read( ); up[u] |= (x << v); dn[v] |= (x << u); } for(int sta = 0; sta < (1 << k); sta ++) { if(dp[now ^ 1][sta]) { int A = 0, B = 0; for(int j = 0; j < k; j ++) A |= (pre[sta & up[j]] << j), B |= (pre[sta & dn[j]] << j); Moc(dp[now][A], dp[now ^ 1][sta]); Moc(dp[now][B], dp[now ^ 1][sta]); } } } int sta = 0; for(int i = 0; i < k; i ++) { int x; x = read( ); sta |= (x << i); } for(int s = 0; s < (1 << k); s ++) { if(! pre[s & sta]) Moc(ans, dp[now][s]); } printf("%lld\n", ans); }
#include <bits/stdc++.h> using namespace std; typedef long long ll; const ll MOD = 998244353; const int STA = (1 << 11) + 5; int m, k; ll ans = 0, dp[2][STA], pre[STA], up[STA], dn[STA]; void init( ) { for(int i = 0; i < (1 << k); i ++) pre[i] = (i & 1) ^ (pre[i >> 1]); } void Moc(ll & a, ll b) { a = (a + b) % MOD; } int read( ) { int t = 1, ans = 0; char x; x = getchar( ); while(x < '0' || x > '9') { if(x == '-') t = -1; x = getchar( ); } while(x >= '0' && x <= '9') { ans = ans * 10 + x - '0'; x = getchar( ); } return ans * t; } int main( ) { freopen("adore.in", "r", stdin); freopen("adore.out", "w", stdout); m = read( ), k = read( ); int s = 0; for(int i = 0; i < k; i ++) { int x; x = read( ); s |= (x << i); } init( ); dp[0][s] = 1; int now = 0; for(int i = 2; i < m - 1; i ++) { now ^= 1; memset(dp[now], 0, sizeof(dp[now])); memset(up, 0, sizeof(up)); memset(dn, 0, sizeof(dn)); for(int u = 0; u < k; u ++) for(int v = 0; v < k; v ++) { int x; x = read( ); up[u] |= (x << v); dn[v] |= (x << u); } for(int sta = 0; sta < (1 << k); sta ++) { if(dp[now ^ 1][sta]) { int A = 0, B = 0; for(int j = 0; j < k; j ++) A |= (pre[sta & up[j]] << j), B |= (pre[sta & dn[j]] << j); Moc(dp[now][A], dp[now ^ 1][sta]); Moc(dp[now][B], dp[now ^ 1][sta]); } } } int sta = 0; for(int i = 0; i < k; i ++) { int x; x = read( ); sta |= (x << i); } for(int s = 0; s < (1 << k); s ++) { if(! pre[s & sta]) Moc(ans, dp[now][s]); } printf("%lld\n", ans); }
对不起这道题正解随机化:))))