POJ2155 Matrix 二维树状数组应用

来源:互联网 发布:apache ant zip maven 编辑:程序博客网 时间:2024/05/16 15:47

        一个N*N(1<=N<=1000)的矩阵,从(1,1)开始,给定一些操作C和一些查询Q,一共K条(1<=K<=50000):

C x1,y1,x2,y2 表示从x1行y1列到x2行y2列的元素全部反转(0变成1,1变成0);

Q x y表示询问x行y列的元素是0还是1。

        题目乍一看感觉还是很难,如果能记录每一个元素的状态值,那答案是显而易见的,但是元素过多,如果每次都对每一个元素进行更新状态的话,复杂度太高。实际上只要记录边界的特定坐标的反转次数,最好的选择那就是二维树状数组了。

        对于操作C,为了保证元素在子矩阵内的反转次数都增加了1,需要在(x1,y1)的位置上加上1,(x2 + 1, y1) 减去1,(x1, y2 + 1)减去1,(x2 +1, y2 + 1)加上1;

        对于操作Q,直接获取Bit(x,y) 的值就代表该元素反转了多少次。

#include <stdlib.h>#include <stdio.h>#include <vector>#include <math.h>#include <string.h>#include <string>#include <iostream>#define MAXN 1001template <class TYPE>void BITAdd(TYPE array[MAXN], int i, TYPE addvalue, int n){while (i <= n){array[i] += addvalue;i += i & -i;}}template <class TYPE>TYPE BITGet(TYPE array[MAXN], int i){TYPE ss = 0;while (i > 0){ss += array[i];i -= i & -i;}return ss;}template <class TYPE>void BIT2DAdd(TYPE array[MAXN][MAXN], int i, int j,TYPE addvalue, int n, int m){while (i <= n){BITAdd<TYPE>(array[i], j, addvalue, m);i += i & -i;}}template <class TYPE>TYPE BIT2DGet(TYPE array[MAXN][MAXN], int i, int j){TYPE ss = 0;while (i > 0){ss += BITGet<TYPE>(array[i], j);i -= i & -i;}return ss;}typedef int MYTYPE;MYTYPE Bit[MAXN][MAXN];int main(){#ifdef _DEBUGfreopen("d:\\in.txt", "r", stdin);#endifint x;scanf("%d", &x);for (int i = 0; i < x; i++){memset(Bit, 0, sizeof(Bit));int n, k;scanf("%d %d\n", &n, &k);if (i >= 1){printf("\n");}for (int j = 0; j < k; j++){char ope;scanf("%c", &ope);if (ope == 'C'){int x1, x2, y1, y2;scanf("%d %d %d %d\n", &x1, &y1, &x2, &y2);BIT2DAdd<int>(Bit, x1, y1, 1, n, n);BIT2DAdd<int>(Bit, x2 + 1, y1, -1, n, n);BIT2DAdd<int>(Bit, x1, y2 + 1, -1, n, n);BIT2DAdd<int>(Bit, x2 + 1, y2 + 1, 1, n, n);}else{int x, y;scanf("%d %d\n", &x, &y);int thisvalue = BIT2DGet<int>(Bit, x, y);printf("%d\n", thisvalue & 1);}}}return 0;}


2 0
原创粉丝点击