现在的位置: 首页 > 综合 > 正文

POJ 2155 Matrix(树状数组+单点更新)

2019年02月11日 ⁄ 综合 ⁄ 共 1262字 ⁄ 字号 评论关闭

好多天没干活了,赶紧更新一篇。


题意:给定一矩阵,初始值均为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;
}

抱歉!评论已关闭.