版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39972971/article/details/89786126
【题目链接】
【思路要点】
- 不难得到 的暴力高斯消元做法。
- 将前 行,第 列的变量作为主元,从上到下、从左到右依次考虑变量 的转移式。
- 可以发现,涉及的变量中只有 未被主元线性表示,因而可以由该转移得到 关于主元的线性表示,若 在棋盘外,那么就可以得到一个关于主元的方程。
- 最终将得到 个变量和等量的方程,采用高斯消元即可。
- 时间复杂度 。
【代码】
#include<bits/stdc++.h> using namespace std; const int MAXN = 205; const int MAXP = 605; const int P = 998244353; const int dx[8] = {-2, -1, 1, 2, 2, 1, -1, -2}; const int dy[8] = {-1, -2, -2, -1, 1, 2, 2, 1}; typedef long long ll; typedef long double ld; typedef unsigned long long ull; template <typename T> void chkmax(T &x, T y) {x = max(x, y); } template <typename T> void chkmin(T &x, T y) {x = min(x, y); } template <typename T> void read(T &x) { x = 0; int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = x * 10 + c - '0'; x *= f; } template <typename T> void write(T x) { if (x < 0) x = -x, putchar('-'); if (x > 9) write(x / 10); putchar(x % 10 + '0'); } template <typename T> void writeln(T x) { write(x); puts(""); } int power(int x, int y) { if (y == 0) return 1; int tmp = power(x, y / 2); if (y % 2 == 0) return 1ll * tmp * tmp % P; else return 1ll * tmp * tmp % P * x % P; } int n, m, q, cnt, tot, sum; int coef[MAXN][MAXN][MAXP]; int p[8], a[MAXP][MAXP], res[MAXP]; void update(int &x, int y) { x += y; if (x >= P) x -= P; } void gauss(int n) { for (int i = 1; i <= n; i++) { for (int j = i; j <= n; j++) if (a[j][i] != 0) { swap(a[i], a[j]); break; } if (a[i][i] == 0) { assert(false); return; } int inv = power(a[i][i], P - 2); for (int j = i + 1; j <= n; j++) { int tmp = 1ll * a[j][i] * inv % P; for (int k = i; k <= n + 1; k++) a[j][k] = (a[j][k] - 1ll * a[i][k] * tmp % P + P) % P; } } for (int i = n; i >= 1; i--) { res[i] = 1ll * power(a[i][i], P - 2) * a[i][n + 1] % P; for (int j = 1; j <= i - 1; j++) if (a[j][i]) update(a[j][n + 1], P - 1ll * res[i] * a[j][i] % P); } } int main() { read(n), read(m); for (int i = 0; i <= 7; i++) read(p[i]), sum += p[i]; sum = power(sum, P - 2); for (int i = 0; i <= 7; i++) p[i] = 1ll * p[i] * sum % P; for (int i = 1; i <= 2; i++) for (int j = 1; j <= m; j++) cnt++, coef[i][j][cnt] = 1; for (int i = 3; i <= n; i++) cnt++, coef[i][1][cnt] = 1; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { if (i + 2 <= n && j + 1 <= m) { coef[i + 2][j + 1][cnt + 1] = P - 1; for (int k = 1; k <= cnt + 1; k++) update(coef[i + 2][j + 1][k], coef[i][j][k]); for (int d = 0; d <= 7; d++) if (d != 4 && i + dx[d] >= 1 && i + dx[d] <= n && j + dy[d] >= 1 && j + dy[d] <= m) { for (int k = 1; k <= cnt + 1; k++) update(coef[i + 2][j + 1][k], P - 1ll * p[d] * coef[i + dx[d]][j + dy[d]][k] % P); } int inv = power(p[4], P - 2); for (int k = 1; k <= cnt + 1; k++) coef[i + 2][j + 1][k] = 1ll * coef[i + 2][j + 1][k] * inv % P; } else { a[++tot][cnt + 1] = P - 1; for (int k = 1; k <= cnt + 1; k++) update(a[tot][k], coef[i][j][k]); for (int d = 0; d <= 7; d++) if (i + dx[d] >= 1 && i + dx[d] <= n && j + dy[d] >= 1 && j + dy[d] <= m) { for (int k = 1; k <= cnt + 1; k++) update(a[tot][k], P - 1ll * p[d] * coef[i + dx[d]][j + dy[d]][k] % P); } a[tot][cnt + 1] = (P - a[tot][cnt + 1]) % P; } } gauss(cnt), read(q); for (int i = 1; i <= q; i++) { int x, y; read(x), read(y); int ans = coef[x][y][cnt + 1]; for (int j = 1; j <= cnt; j++) update(ans, 1ll * res[j] * coef[x][y][j] % P); writeln(ans); } return 0; }