QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#684283 | #1185. To argue, or not to argue | rlc202204 | AC ✓ | 2760ms | 10128kb | C++17 | 3.0kb | 2024-10-28 12:10:10 | 2024-10-28 12:10:11 |
Judging History
answer
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 14;
const int mod = 1e9 + 7;
const int MS = (1 << 12) + 5;
int fpow(int a, int b, int p) {
if (b == 0)
return 1;
int ans = fpow(a, b / 2, p);
ans = 1ll * ans * ans % p;
if (b % 2 == 1)
ans = 1ll * a * ans % p;
return ans;
}
int mmi(int a, int p) {
return fpow(a, p - 2, p);
}
int fac[N * N] = {0}, inv[N * N] = {0};
void init(int n) {
fac[0] = 1;
for (int i = 1; i <= n; i++)
fac[i] = 1ll * i * fac[i - 1] % mod;
inv[n] = mmi(fac[n], mod);
for (int i = n - 1; i >= 0; i--)
inv[i] = 1ll * (i + 1) * inv[i + 1] % mod;
}
int A(int n, int k) {
return 1ll * fac[n] * inv[n - k] % mod;
}
void add(int &x, int y) {
x = (x + y) % mod;
}
int n, m, k;
char mp[N * N][N * N], mp2[N * N][N * N];
int f[N * N][MS] = {{0}};
int f2[N * N][MS] = {{0}};
void show(int S) {
for (int j = 0; j < n; j++)
cout << (S >> j & 1);
}
int tmp[N * N] = {0}, len = 0;
void dfs(int x, int col, int S, int nS, int cnt) {//当前是第 x 个,第 col 列,上一列是 S,这一列目前是 nS,用了 cnt 个了
if (x > n) {
for (int j = 1; j <= len && tmp[j] + cnt <= k; j++)
add(f[tmp[j] + cnt][nS], f2[tmp[j]][S]);
return;
}
if ((S >> (x - 1) & 1)) {//被预定了
if (mp[x][col] != 'X')
dfs(x + 1, col, S, nS, cnt + 1);
}
else if (mp[x][col] == 'X') {
dfs(x + 1, col, S, nS, cnt);
}
else {
if (x < n && mp[x + 1][col] != 'X' && !(S >> x & 1)) {
dfs(x + 2, col, S, nS, cnt + 1);
}
dfs(x + 1, col, S, nS, cnt);
dfs(x + 1, col, S, nS + (1 << (x - 1)), cnt);
}
}
int pw[N * N] = {0};
void slv() {
scanf("%d%d%d", &n, &m, &k);
init(n * m);
int cnt = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf(" %c", &mp[i][j]), cnt += (mp[i][j] == '.');
if (n > m) {
swap(n, m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
mp2[i][j] = mp[j][i];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
mp[i][j] = mp2[i][j];
}
memset(f, 0, sizeof f);
f[0][0] = 1;
for (int i = 0; i < m; i++) {
memcpy(f2, f, sizeof f2);
memset(f, 0, sizeof f);
for (int S = 0; S < (1 << n); S++) {
len = 0;
for (int j = 0; j <= i * n / 2; j++)
if (f2[j][S] > 0)
tmp[++len] = j;
if (len > 0)
dfs(1, i + 1, S, 0, 0);
}
}
pw[0] = 1;
for (int i = 1; i <= k; i++)
pw[i] = 2ll * pw[i - 1] % mod;
int ans = 0;
for (int i = 0; i <= k; i++)
if (i % 2 == 0) {
// cout << i << " ? " << f[m][i][0] << endl;
add(ans, 1ll * f[i][0] * A(k, i) % mod * pw[i] % mod * A(cnt - i * 2, 2 * k - 2 * i) % mod);
}
else {
// cout << i << " ? " << f[m][i][0] << endl;
add(ans, (mod - 1ll * f[i][0] * A(k, i) % mod * pw[i] % mod * A(cnt - i * 2, 2 * k - 2 * i) % mod) % mod);
}
printf("%d\n", ans);
}
int main() {
// freopen("test.in", "r", stdin);
int T;
scanf("%d", &T);
while (T--)
slv();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 4ms
memory: 10084kb
input:
2 2 2 2 .. .. 4 4 3 X.X. .... .X.. ...X
output:
8 347040
result:
ok 2 number(s): "8 347040"
Test #2:
score: 0
Accepted
time: 2760ms
memory: 10128kb
input:
96 1 144 8 ................................................................................................................................................ 144 1 31 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ....
output:
517668733 268886110 64664470 926220403 0 0 372341012 839870997 115795952 169129272 928175112 399452284 981581814 563968454 82030165 770277954 161484719 374884294 988612558 269599606 838995341 614914000 779550646 19224822 195892020 368899964 857064056 437999888 225342223 836336621 981420655 30328633 ...
result:
ok 96 numbers