QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#360911 | #8173. T Tile Placement Counting | ucup-team1198 | AC ✓ | 683ms | 6940kb | C++14 | 7.7kb | 2024-03-22 15:27:51 | 2024-03-22 15:27:52 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int MOD = 998244353;
int add(int a, int b) {
return a + b >= MOD ? a + b - MOD : a + b;
}
int sub(int a, int b) {
return a >= b ? a - b : a + MOD - b;
}
int mul(int a, int b) {
return (1ll * a * b) % MOD;
}
int pw(int x, int n) {
int res = 1;
while (n) {
if (n % 2 == 0) {
x = mul(x, x);
n /= 2;
} else {
res = mul(res, x);
--n;
}
}
return res;
}
const int MAXN = 7;
vector<int> g[MAXN * 4];
void clear_g(int n) {
for (int i = 0; i < 2 * n; ++i) {
g[i].clear();
}
}
void add_start(const string& s) {
int n = s.size();
vector<int> st;
for (int i = 0; i < n; ++i) {
if (s[i] == '(') {
st.push_back(i);
} else {
g[st.back()].push_back(i);
g[i].push_back(st.back());
st.pop_back();
}
}
}
void add_square(int n, int i, int c) {
if (c == 0) {
g[i].push_back(i + 1);
g[i + 1].push_back(i);
g[i + n].push_back(i + 1 + n);
g[i + 1 + n].push_back(i + n);
} else {
g[i].push_back(i + n);
g[i + n].push_back(i);
g[i + 1].push_back(i + 1 + n);
g[i + 1 + n].push_back(i + 1);
}
}
pair<string, int> get(int n) {
vector<int> used(2 * n);
string s;
for (int i = n; i < 2 * n; ++i) {
if (used[i]) {
s.push_back(')');
continue;
}
s.push_back('(');
int j = i;
while (j != -1) {
used[j] = 1;
int nj = -1;
for (int j1 : g[j]) {
if (!used[j1]) {
nj = j1;
break;
}
}
j = nj;
}
}
int cnt = 1;
for (int i = 0; i < n; ++i) {
if (used[i]) {
continue;
}
int j = i;
while (j != -1) {
used[j] = 1;
int nj = -1;
for (int j1 : g[j]) {
if (!used[j1]) {
nj = j1;
break;
}
}
j = nj;
}
cnt *= 2;
}
return {s, cnt};
}
vector<string> all;
void gen(string cur, int bal, int n) {
if ((int)cur.size() == n) {
if (bal == 0) {
all.push_back(cur);
}
return;
}
if (bal > 0) {
cur.push_back(')');
gen(cur, bal - 1, n);
cur.pop_back();
}
if (bal + 1 <= n - (int)cur.size() - 1) {
cur.push_back('(');
gen(cur, bal + 1, n);
cur.pop_back();
}
}
vector<vector<int>> operator*(const vector<vector<int>>& a, const vector<vector<int>>& b) {
int n = a.size();
int m = a[0].size();
int k = b[0].size();
vector<vector<int>> c(n, vector<int>(k, 0));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < k; ++j) {
for (int p = 0; p < m; ++p) {
c[i][j] = add(c[i][j], mul(a[i][p], b[p][j]));
}
}
}
return c;
}
vector<int> operator*(const vector<int>& a, const vector<int>& b) {
vector<int> c(a.size() + b.size() - 1);
for (int i = 0; i < (int)a.size(); ++i) {
for (int j = 0; j < (int)b.size(); ++j) {
c[i + j] = add(c[i + j], mul(a[i], b[j]));
}
}
return c;
}
void cut(vector<int>& a, const vector<int>& p) {
int n = p.size();
while (a.size() > p.size()) {
for (int i = 0; i < n; ++i) {
a[a.size() - n - 1 + i] = add(a[a.size() - n - 1 + i], mul(a.back(), p[i]));
}
a.pop_back();
}
}
vector<int> binpow(vector<int> x, int64_t m, const vector<int>& p) {
vector<int> res = {1};
while (m) {
if (m % 2 == 0) {
x = x * x;
cut(x, p);
m /= 2;
} else {
res = res * x;
cut(res, p);
--m;
}
}
return res;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int h;
int64_t w;
cin >> h >> w;
if (h % 4 != 0 || w % 4 != 0) {
cout << "0\n";
return 0;
}
h /= 2; w /= 2;
gen("", 0, h);
map<string, int> id;
int C = all.size();
for (int i = 0; i < C; ++i) {
id[all[i]] = i;
}
vector<vector<int>> s(C, vector<int>(1, 0));
vector<vector<int>> PtB(C, vector<int>(C, 0));
vector<vector<int>> BtP(C, vector<int>(C, 0));
vector<vector<int>> t(1, vector<int>(C, 0));
s[0][0] = 1;
for (int i = 0; i < C; ++i) {
clear_g(h);
add_start(all[i]);
for (int j = 0; j < h; j += 2) {
add_square(h, j, 0);
}
auto res = get(h);
t[0][i] = res.second;
}
for (int i = 0; i < C; ++i) {
for (int mask = 0; mask < (1 << (h / 2)); ++mask) {
clear_g(h);
add_start(all[i]);
for (int j = 0; j < h; j += 2) {
if (mask & (1 << (j / 2))) {
add_square(h, j, 1);
} else {
add_square(h, j, 0);
}
}
auto res = get(h);
BtP[id[res.first]][i] = add(BtP[id[res.first]][i], res.second);
}
}
for (int i = 0; i < C; ++i) {
for (int mask = 0; mask < (1 << (h / 2 - 1)); ++mask) {
clear_g(h);
add_start(all[i]);
g[0].push_back(h);
g[h].push_back(0);
g[h - 1].push_back(2 * h - 1);
g[2 * h - 1].push_back(h - 1);
for (int j = 1; j + 1 < h; j += 2) {
if (mask & (1 << (j / 2))) {
add_square(h, j, 1);
} else {
add_square(h, j, 0);
}
}
auto res = get(h);
/// cerr << all[i] << "->" << res.first << " " << res.second << endl;
PtB[id[res.first]][i] = add(PtB[id[res.first]][i], res.second);
}
}
t = t * PtB;
vector<vector<int>> A = BtP * PtB;
int64_t m = w / 2 - 1;
/// t*A^m*s
vector<int> val(2 * C);
for (int i = 0; i < 2 * C; ++i) {
val[i] = (t * s)[0][0];
s = A * s;
}
vector<vector<int>> eq(C, vector<int>(C + 1, 0));
for (int i = 0; i < C; ++i) {
for (int k = 0; k <= C; ++k) {
eq[i][k] = val[i + k];
}
}
int col = 0;
vector<array<int, 2>> var;
for (int i = 0; i < C && col < C; ++i) {
int id = -1;
for (int j = i; j < C; ++j) {
if (eq[j][i] != 0) {
id = j;
break;
}
}
if (id == -1) {
++col;
--i;
continue;
}
swap(eq[i], eq[id]);
var.push_back({col, i});
int anti = pw(eq[i][i], MOD - 2);
for (int j = 0; j <= C; ++j) {
eq[i][j] = mul(eq[i][j], anti);
}
for (int j = 0; j < C; ++j) {
if (j == i) continue;
int val = eq[j][i];
for (int k = 0; k <= C; ++k) {
eq[j][k] = sub(eq[j][k], mul(val, eq[i][k]));
}
}
++col;
}
vector<int> p(C);
for (auto elem : var) {
p[elem[0]] = eq[elem[1]][C];
}
vector<int> x = {0, 1};
x = binpow(x, m, p);
int ans = 0;
for (int i = 0; i < C; ++i) {
ans = add(ans, mul(x[i], val[i]));
}
cout << ans << "\n";
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3612kb
input:
4 4
output:
2
result:
ok "2"
Test #2:
score: 0
Accepted
time: 0ms
memory: 3664kb
input:
2 8
output:
0
result:
ok "0"
Test #3:
score: 0
Accepted
time: 0ms
memory: 3704kb
input:
12 3456
output:
491051233
result:
ok "491051233"
Test #4:
score: 0
Accepted
time: 0ms
memory: 3672kb
input:
1 1
output:
0
result:
ok "0"
Test #5:
score: 0
Accepted
time: 0ms
memory: 3608kb
input:
20 999999999999999983
output:
0
result:
ok "0"
Test #6:
score: 0
Accepted
time: 0ms
memory: 3908kb
input:
24 999999999999999994
output:
0
result:
ok "0"
Test #7:
score: 0
Accepted
time: 0ms
memory: 3836kb
input:
24 999999999999999955
output:
0
result:
ok "0"
Test #8:
score: 0
Accepted
time: 675ms
memory: 6648kb
input:
28 999999999999999928
output:
846645622
result:
ok "846645622"
Test #9:
score: 0
Accepted
time: 0ms
memory: 3616kb
input:
28 999999999999999971
output:
0
result:
ok "0"
Test #10:
score: 0
Accepted
time: 0ms
memory: 3672kb
input:
28 999999999999999901
output:
0
result:
ok "0"
Test #11:
score: 0
Accepted
time: 0ms
memory: 3616kb
input:
28 999999999999999945
output:
0
result:
ok "0"
Test #12:
score: 0
Accepted
time: 0ms
memory: 3672kb
input:
30 1000000000000000000
output:
0
result:
ok "0"
Test #13:
score: 0
Accepted
time: 0ms
memory: 3840kb
input:
4 144115188075855868
output:
479168365
result:
ok "479168365"
Test #14:
score: 0
Accepted
time: 0ms
memory: 3668kb
input:
4 288230376151711740
output:
661413713
result:
ok "661413713"
Test #15:
score: 0
Accepted
time: 0ms
memory: 3608kb
input:
4 576460752303423484
output:
854857972
result:
ok "854857972"
Test #16:
score: 0
Accepted
time: 0ms
memory: 3904kb
input:
8 144115188075855868
output:
266363233
result:
ok "266363233"
Test #17:
score: 0
Accepted
time: 0ms
memory: 3664kb
input:
8 288230376151711740
output:
862901307
result:
ok "862901307"
Test #18:
score: 0
Accepted
time: 0ms
memory: 3608kb
input:
8 576460752303423484
output:
455991900
result:
ok "455991900"
Test #19:
score: 0
Accepted
time: 0ms
memory: 3672kb
input:
12 144115188075855868
output:
226857121
result:
ok "226857121"
Test #20:
score: 0
Accepted
time: 0ms
memory: 3904kb
input:
12 288230376151711740
output:
717445399
result:
ok "717445399"
Test #21:
score: 0
Accepted
time: 0ms
memory: 3608kb
input:
12 576460752303423484
output:
935277864
result:
ok "935277864"
Test #22:
score: 0
Accepted
time: 1ms
memory: 3692kb
input:
16 144115188075855868
output:
631950327
result:
ok "631950327"
Test #23:
score: 0
Accepted
time: 1ms
memory: 3680kb
input:
16 288230376151711740
output:
73767413
result:
ok "73767413"
Test #24:
score: 0
Accepted
time: 1ms
memory: 3676kb
input:
16 576460752303423484
output:
329402693
result:
ok "329402693"
Test #25:
score: 0
Accepted
time: 2ms
memory: 3728kb
input:
20 144115188075855868
output:
125405814
result:
ok "125405814"
Test #26:
score: 0
Accepted
time: 2ms
memory: 3924kb
input:
20 288230376151711740
output:
794579293
result:
ok "794579293"
Test #27:
score: 0
Accepted
time: 0ms
memory: 3960kb
input:
20 576460752303423484
output:
726571847
result:
ok "726571847"
Test #28:
score: 0
Accepted
time: 27ms
memory: 4200kb
input:
24 144115188075855868
output:
310529292
result:
ok "310529292"
Test #29:
score: 0
Accepted
time: 28ms
memory: 3996kb
input:
24 288230376151711740
output:
493789216
result:
ok "493789216"
Test #30:
score: 0
Accepted
time: 25ms
memory: 3984kb
input:
24 576460752303423484
output:
606221157
result:
ok "606221157"
Test #31:
score: 0
Accepted
time: 682ms
memory: 6940kb
input:
28 144115188075855868
output:
964541053
result:
ok "964541053"
Test #32:
score: 0
Accepted
time: 679ms
memory: 6868kb
input:
28 288230376151711740
output:
42971353
result:
ok "42971353"
Test #33:
score: 0
Accepted
time: 683ms
memory: 6736kb
input:
28 576460752303423484
output:
179569141
result:
ok "179569141"
Test #34:
score: 0
Accepted
time: 0ms
memory: 3648kb
input:
6 5
output:
0
result:
ok "0"
Test #35:
score: 0
Accepted
time: 0ms
memory: 3560kb
input:
14 28
output:
0
result:
ok "0"
Test #36:
score: 0
Accepted
time: 0ms
memory: 3608kb
input:
25 6365
output:
0
result:
ok "0"
Test #37:
score: 0
Accepted
time: 0ms
memory: 3876kb
input:
18 529543996
output:
0
result:
ok "0"
Test #38:
score: 0
Accepted
time: 1ms
memory: 3608kb
input:
10 675199829716849556
output:
0
result:
ok "0"
Test #39:
score: 0
Accepted
time: 2ms
memory: 3720kb
input:
20 425279816112802872
output:
269059955
result:
ok "269059955"
Test #40:
score: 0
Accepted
time: 0ms
memory: 3608kb
input:
8 38212554426330756
output:
207344318
result:
ok "207344318"
Test #41:
score: 0
Accepted
time: 26ms
memory: 3936kb
input:
24 666881067086698696
output:
245351821
result:
ok "245351821"
Test #42:
score: 0
Accepted
time: 0ms
memory: 3640kb
input:
4 728683474913510792
output:
466882081
result:
ok "466882081"
Test #43:
score: 0
Accepted
time: 672ms
memory: 6704kb
input:
28 201838304882525604
output:
217184228
result:
ok "217184228"
Test #44:
score: 0
Accepted
time: 0ms
memory: 3668kb
input:
4 8560
output:
596875387
result:
ok "596875387"
Test #45:
score: 0
Accepted
time: 0ms
memory: 3644kb
input:
12 60764
output:
930662011
result:
ok "930662011"
Test #46:
score: 0
Accepted
time: 0ms
memory: 3904kb
input:
8 45272
output:
239612337
result:
ok "239612337"
Test #47:
score: 0
Accepted
time: 0ms
memory: 3672kb
input:
8 84616
output:
826857610
result:
ok "826857610"
Test #48:
score: 0
Accepted
time: 0ms
memory: 3640kb
input:
4 316408
output:
529567983
result:
ok "529567983"
Test #49:
score: 0
Accepted
time: 0ms
memory: 3912kb
input:
8 12
output:
1182
result:
ok "1182"
Test #50:
score: 0
Accepted
time: 0ms
memory: 3872kb
input:
8 16
output:
16644
result:
ok "16644"
Test #51:
score: 0
Accepted
time: 0ms
memory: 3904kb
input:
4 8
output:
6
result:
ok "6"
Test #52:
score: 0
Accepted
time: 0ms
memory: 3656kb
input:
12 16
output:
5253822
result:
ok "5253822"
Extra Test:
score: 0
Extra Test Passed