| |
| |
| #include <bits/stdc++.h> |
| using namespace std; |
|
|
| constexpr int P = 998244353; |
|
|
| struct MInt { |
| int x; |
| MInt(): x(0) {} |
| MInt(long long v): x(int((v % P + P) % P)) {} |
| MInt operator+(const MInt& b) const { int r = x + b.x; return MInt(r >= P ? r - P : r); } |
| MInt operator-(const MInt& b) const { int r = x - b.x; return MInt(r < 0 ? r + P : r); } |
| MInt operator*(const MInt& b) const { return MInt(1LL * x * b.x % P); } |
| bool operator==(const MInt& b) const { return x == b.x; } |
| bool operator!=(const MInt& b) const { return x != b.x; } |
| }; |
|
|
| int main(int argc, char* argv[]) { |
| long long k; |
| cin >> k; |
| MInt target(k); |
|
|
| int n; |
| cin >> n; |
| if (n < 1 || n > 512) { |
| cerr << "Invalid n=" << n << endl; |
| return 1; |
| } |
|
|
| |
| |
| vector<vector<int>> a(n); |
| for (int i = 0; i < n; i++) { |
| string s; |
| cin >> s; |
| if (s == "POP") { |
| a[i].resize(4); |
| cin >> a[i][0]; |
| string tmp; |
| cin >> tmp; |
| cin >> a[i][1]; |
| a[i][1]--; |
| cin >> tmp; |
| cin >> a[i][2]; |
| cin >> tmp; |
| cin >> a[i][3]; |
| a[i][3]--; |
| if (a[i][0] < 1 || a[i][0] > 1024 || a[i][2] < 1 || a[i][2] > 1024) { |
| cerr << "Char out of range at instruction " << i+1 << endl; |
| return 1; |
| } |
| if (a[i][1] < 0 || a[i][1] >= n || a[i][3] < 0 || a[i][3] >= n) { |
| cerr << "Goto out of range at instruction " << i+1 << endl; |
| return 1; |
| } |
| } else if (s == "HALT") { |
| a[i].resize(2); |
| string tmp; |
| cin >> tmp; |
| cin >> a[i][0]; |
| cin >> tmp; |
| cin >> a[i][1]; |
| a[i][1]--; |
| if (a[i][0] < 1 || a[i][0] > 1024) { |
| cerr << "Char out of range at instruction " << i+1 << endl; |
| return 1; |
| } |
| if (a[i][1] < 0 || a[i][1] >= n) { |
| cerr << "Goto out of range at instruction " << i+1 << endl; |
| return 1; |
| } |
| } else { |
| cerr << "Unknown instruction type: " << s << " at line " << i+1 << endl; |
| return 1; |
| } |
| } |
|
|
| |
| vector<array<optional<pair<int, MInt>>, 1025>> dp(n); |
| vector<array<bool, 1025>> vis(n, array<bool, 1025>{}); |
|
|
| bool infinite = false; |
|
|
| function<pair<int, MInt>(int, int)> solve = [&](int i, int x) -> pair<int, MInt> { |
| if (dp[i][x]) return dp[i][x].value(); |
| if (vis[i][x]) { |
| infinite = true; |
| return {-1, MInt(0)}; |
| } |
| vis[i][x] = true; |
|
|
| if (a[i].size() == 4) { |
| |
| if (x == a[i][0]) { |
| dp[i][x] = {a[i][1], MInt(1)}; |
| } else { |
| auto [j, u] = solve(a[i][3], a[i][2]); |
| if (infinite) return {-1, MInt(0)}; |
| auto [kk, v] = solve(j, x); |
| if (infinite) return {-1, MInt(0)}; |
| dp[i][x] = {kk, u + v + MInt(1)}; |
| } |
| } else { |
| |
| if (x == 0) { |
| dp[i][x] = {-1, MInt(1)}; |
| } else { |
| auto [j, u] = solve(a[i][1], a[i][0]); |
| if (infinite) return {-1, MInt(0)}; |
| auto [kk, v] = solve(j, x); |
| if (infinite) return {-1, MInt(0)}; |
| dp[i][x] = {kk, u + v + MInt(1)}; |
| } |
| } |
| return dp[i][x].value(); |
| }; |
|
|
| auto [final_instr, steps] = solve(0, 0); |
|
|
| if (infinite) { |
| cout << "INFINITE (never halts)" << endl; |
| return 1; |
| } |
|
|
| cout << "n=" << n << " steps_mod_P=" << steps.x << " target_mod_P=" << target.x; |
| if (steps == target) { |
| cout << " CORRECT"; |
| double ratio = 1.0 * (512 - n) / 512; |
| cout << " score=" << ratio; |
| } else { |
| cout << " WRONG"; |
| } |
| cout << endl; |
|
|
| return 0; |
| } |
|
|