该题就是简单的二维树状数组,保留一份棋盘的最新状态即可,树状数组里面就只保留在原有基础上增加或者减少的某一种饺子的数量。
代码如下:
#include <cstring> #include <cstdlib> #include <cstdio> using namespace std;char op[5];char G[1050][1050];int cc[1050][1050]; // 数组中存储韭菜饺的数量,白菜饺的数量通过总数量减去韭菜饺来求void init() {int k = 0; // 定义韭菜为1,白菜为0for (int i = 1; i <= 1024; ++i) {for (int j = 1; j <= 1025; ++j) { // 由于一行的结束和另一行的开始种类相同,所以多加了一列来翻转kG[i][j] = (k ^= 1);}} }int lowbit(int x) {return x & -x; }void modify(int x, int y, int val) {for (int i = x; i <= 1024; i += lowbit(i)) {for (int j = y; j <= 1024; j += lowbit(j)) {cc[i][j] += val;}} }int sum(int x, int y) {int tot = 0;for (int i = x; i > 0; i -= lowbit(i)) {for (int j = y; j > 0; j -= lowbit(j)) { tot += cc[i][j];}}return tot; }int main() {int T, a, b, c, d, k;int A, B, C, S;while (scanf("%d", &T) == 1) {init();memset(cc, 0, sizeof (cc));while (T--) { scanf("%s", op);if (op[0] == 'R') {scanf("%d %d %d %d", &a, &b, &c, &d);A = sum(c, d) - sum(c, b-1) - sum(a-1, d) + sum(a-1, b-1);if ((a + b) & 1) { // 白菜多数S = (c-a+1)*(d-b+1) / 2;}else {S = ((c-a+1)*(d-b+1) + 1)/ 2;}B = S + A;C = (c-a+1)*(d-b+1) - B;printf("%d %d\n", B, C);}else { // 'A' 为韭菜,‘B’ 为白菜scanf("%d %d", &a, &b);k = op[0] == 'A'; // 1为韭菜,0为白菜if (k != G[a][b]) {G[a][b] = k;if (k) {modify(a, b, 1);}else {modify(a, b, -1);}}}}}return 0; }