POJ 2155 Matrix(树状数组+单点更新)
2015-02-21 17:30
127 查看
好多天没干活了,赶紧更新一篇。
题意:给定一矩阵,初始值均为0。现有两种操作:1.将以(x1, y1)为左上角,(x2, y2)为右下角的矩阵中的所有0变为1,所有1变为0;2.查询位置(x, y)是0还是1。
要点:
1.sum(i)是求第i位的前缀和,add(i)是更新位置i的单点值。
2.翻转两次相当于没有翻转。
假设x为位置i的翻转次数,那么可以将x看做一个集合,x = { x + 2 * k | k = 整数 }【格式不是很标准,意会一下】;
令i的前缀和为位置i的翻转次数的集合中的一个元素。
假设要给绿色部分都反转,那么绿色部分里面的每个点的前缀和都要加一个奇数,比如1;
可给绿色部分的左上角加一,这样绿色部分的每个点求前缀和的时候都会加一了;
但是这样紫色部分和肤色部分还有粉红色部分也加了一;
所以还要加,把三个部分加成偶数;
于是加绿色右上角,绿色左下角,绿色右下角都加1;
这样肤色和粉色部分的前缀和都加了2,紫色部分是加了4,消除了绿色左上角加一的影响。
剩下的就是二维树状数组乱搞了。
题意:给定一矩阵,初始值均为0。现有两种操作:1.将以(x1, y1)为左上角,(x2, y2)为右下角的矩阵中的所有0变为1,所有1变为0;2.查询位置(x, y)是0还是1。
要点:
1.sum(i)是求第i位的前缀和,add(i)是更新位置i的单点值。
2.翻转两次相当于没有翻转。
假设x为位置i的翻转次数,那么可以将x看做一个集合,x = { x + 2 * k | k = 整数 }【格式不是很标准,意会一下】;
令i的前缀和为位置i的翻转次数的集合中的一个元素。
假设要给绿色部分都反转,那么绿色部分里面的每个点的前缀和都要加一个奇数,比如1;
可给绿色部分的左上角加一,这样绿色部分的每个点求前缀和的时候都会加一了;
但是这样紫色部分和肤色部分还有粉红色部分也加了一;
所以还要加,把三个部分加成偶数;
于是加绿色右上角,绿色左下角,绿色右下角都加1;
这样肤色和粉色部分的前缀和都加了2,紫色部分是加了4,消除了绿色左上角加一的影响。
剩下的就是二维树状数组乱搞了。
#include <algorithm> #include <iostream> #include <stdlib.h> #include <string.h> #include <stdio.h> using namespace std; #define MAXN 1005 int s[MAXN][MAXN]; char o[4]; int x1, x2, y1, y2, n, q, ans; inline int lowbit(int x) { return x & (-x); } int sum(int i, int j) { int ret = 0; while(i > 0) { int tj = j; while(tj > 0) { ret += s[i][tj]; tj -= lowbit(tj); } i -= lowbit(i); } return ret; } void add(int i, int j) { while(i <= n) { int tj = j; while(tj <= n) { s[i][tj]++; tj += lowbit(tj); } i += lowbit(i); } } int main() { // freopen("B.in", "r", stdin); int t; scanf("%d", &t); bool flag = false; while(t--) { if(flag) puts(""); if(!flag) flag = true; scanf("%d%d", &n, &q); memset(s, 0, sizeof(s)); while(q--) { scanf("%s", o); if(o[0] == 'C') { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); add(x1, y1); add(x1, y2 + 1); add(x2 + 1, y1); add(x2 + 1, y2 + 1); } if(o[0] == 'Q') { scanf("%d%d", &x1, &y1); ans = sum(x1, y1);// - sum(x1, y1 - 1) - sum(x1 - 1, y1) + sum(x1 - 1, y1 - 1); printf("%d\n", ans & 1); } } } return 0; }
相关文章推荐
- POJ 2155 - Matrix 二维树状数组..区间更新..单点查询
- POJ 2155 Matrix (二维线段树入门,成段更新,单点查询 / 二维树状数组,区间更新,单点查询)
- POJ - 2155 Matrix (二维树状数组 + 区间修改 + 单点求值 或者 二维线段树 + 区间更新 + 单点求值)
- poj 2155 Matrix 树状数组 区间更新单点求值
- poj2155-二维树状数组 区间更新 单点查询
- poj 2155- Matrix (树状数组,二维,更新区间,查询单点)
- POJ 2155 Matrix(二维树状数组+数组数组区间更新+单点查询)
- poj 2155 第一天学树状数组,还没怎么搞清楚二维的区间更新单点查询
- poj 2155(二维树状数组,区间更新,单点查询)
- POJ 2155 Matrix (树状数组,区间更新转成点更新)
- POJ 2155 Matrix (二维树状数组,区间更新,点查找)
- POJ 2155-Matrix(二维树状数组-区间修改 单点查询)
- Matrix (POJ - 2155 )(树状数组的区间更新-点查询)
- POJ 2155 矩阵(二维树状数组 区间更新 单点查找)
- POJ 2155 Matrix (二维树状数组,区间更新,点查找)
- poj 2155 Matrix(二维树状数组,好题)中等难度题目,更新区域,查询单点
- poj 2155 二维树状数组/区间更新单点查询
- POJ 2155 Matrix 【树状数组 更新区间 求点】
- POJ 1195 - Mobile phones 二维树状数组(单点更新..区间查询)
- POJ2155 Matrix 【二维树状数组】+【段更新点查询】