ICPC2025Online2 E Zero
# ICPC2025Online2 E Zero
ICPC2025Online2 E Zero (opens new window)
# Solution
设 表示长度为 的序列,值域为 的答案
我们能构造如下递推柿子
第一行随便放,方案为 ,第二行到第 行,不能和上一行一样,方案数为
以及放了 行,最后一行就已经确定了
但是此时有可能最后一行和最后一行一样,我们需要减掉这样的方案,由于最后两位的异或为 0,所以要减去 ,于是得到递推式
这个东西是线性的,于是可以用矩阵快速幂来求解,但不是常系数的,所以需要增加一维记录
分奇偶快速幂就好了
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
constexpr int P = 998244353;
int norm(int x) {
if (x < 0) {
x += P;
}
if (x >= P) {
x -= P;
}
return x;
}
template<class T>
T power(T a, i64 b) {
T res = 1;
for (; b; b /= 2, a *= a) {
if (b % 2) {
res *= a;
}
}
return res;
}
struct Z {
int x;
Z (int x = 0) : x(norm(x)) {}
int val() const {
return x;
}
Z operator - () const {
return Z(norm(P - x));
}
Z inv() const {
// assert(x != 0);
if (x == 0) {
return 1;
}
return power(*this, P - 2);
}
Z &operator *= (const Z &rhs) {
x = i64(x) * rhs.x % P;
return *this;
}
Z &operator += (const Z &rhs) {
x = norm(x + rhs.x);
return *this;
}
Z &operator -= (const Z &rhs) {
x = norm(x - rhs.x);
return *this;
}
Z &operator /= (const Z &rhs) {
return *this *= rhs.inv();
}
friend Z operator * (const Z &lhs, const Z &rhs) {
Z res = lhs;
res *= rhs;
return res;
}
friend Z operator + (const Z &lhs, const Z &rhs) {
Z res = lhs;
res += rhs;
return res;
}
friend Z operator - (const Z &lhs, const Z &rhs) {
Z res = lhs;
res -= rhs;
return res;
}
friend Z operator / (const Z &lhs, const Z &rhs) {
Z res = lhs;
res /= rhs;
return res;
}
friend std::istream &operator >> (std::istream &is, Z &a) {
i64 v;
is >> v;
a = Z(v);
return is;
}
friend std::ostream &operator << (std::ostream &os, const Z &a) {
return os << a.val();
}
};
struct Matrix : array<array<Z, 3>, 3> {
Matrix() {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
(*this)[i][j] = Z(0);
}
}
}
friend Matrix operator * (const Matrix &a, const Matrix &b) {
Matrix res;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
res[i][j] += a[i][k] * b[k][j];
}
}
}
return res;
}
};
Matrix qpow(Matrix a, i64 b) {
Matrix res = Matrix();
for (int i = 0; i < 3; i++)
res[i][i] = 1;
while (b) {
if (b & 1) { res = res * a; }
a = a * a;
b = b >> 1;
}
return res;
}
void solve() {
i64 n, m; cin >> n >> m;
if (n == 1) {
cout << 1 << '\n';
return ;
}
Z g = power(Z(2), m) - Z(1);
Matrix A;
A[0][0] = -g; A[0][2] = g + 1; A[1][0] = 1; A[2][2] = g * g;
Matrix a0;
i64 exp;
if (n % 2 == 0) {
a0[0][0] = 0;
a0[1][0] = 0;
a0[2][0] = g * g;
exp = (n - 2) / 2;
}
else {
a0[0][0] = g * g;
a0[1][1] = 0;
a0[2][0] = g * g * g;
exp = (n - 3) / 2;
}
Matrix ans = qpow(A, exp) * a0;
cout << ans[0][0] << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cin.tie(nullptr);
int t; cin >> t;
while (t--) {solve();}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164