poj 2155 Matrix(二维树状数组)

Matrix
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 26929 Accepted: 9867

Description

Given an N*N matrix A, whose elements are either 0 or 1. A[i, j] means the number in the i-th row and j-th column. Initially we have A[i, j] = 0 (1 <= i, j <= N). 

We can change the matrix in the following way. Given a rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2), we change all the elements in the rectangle by using "not" operation (if it is a '0' then change it into '1' otherwise change it into '0'). To maintain the information of the matrix, you are asked to write a program to receive and execute two kinds of instructions. 

1. C x1 y1 x2 y2 (1 <= x1 <= x2 <= n, 1 <= y1 <= y2 <= n) changes the matrix by using the rectangle whose upper-left corner is (x1, y1) and lower-right corner is (x2, y2). 
2. Q x y (1 <= x, y <= n) querys A[x, y]. 

Input

The first line of the input is an integer X (X <= 10) representing the number of test cases. The following X blocks each represents a test case. 

The first line of each block contains two numbers N and T (2 <= N <= 1000, 1 <= T <= 50000) representing the size of the matrix and the number of the instructions. The following T lines each represents an instruction having the format "Q x y" or "C x1 y1 x2 y2", which has been described above. 

Output

For each querying output one line, which has an integer representing A[x, y]. 

There is a blank line between every two continuous test cases. 

Sample Input

1
2 10
C 2 1 2 2
Q 2 2
C 2 1 2 1
Q 1 1
C 1 1 2 1
C 1 2 1 2
C 1 1 2 2
Q 1 1
C 1 1 2 1
Q 2 1

Sample Output

1
0
0
1


这个题暴力肯定是不能过的,这个地方利用了二维树状数组来维护。

不会二维树状数组的请仔细查看博客一维与二维树状数组。

老实说一开始看题解,是怎么也看不懂,实际上树状数组的功能确实没问题,然而在理解上有一些问题。

首先要明确树状数组的板子代表的意思。

假设参数都是x,y,val。

1.updata函数,更新的是a[x][y]的值。

2.ask函数,查询出来的是以(1,1)为左上角以(x,y)为右下角的子矩阵的和!!!!

对于这个题怎么来做呢,这个地方其实是利用了用标记来消除影响的一个效果。

譬如说对于一个1维数组,你要更新区间(l,r)的值,那么你可以让a[l]+val,让a[r+1]-val,这样你从左端加到右端(假设为x)的时候(前缀和)算出来的a[x]的值是正确的。

就是说每一个a[i]的值都是这样得到的a[i]+=a[i-1]。

可以在纸上画一画,便知道了。

然后这个题其实就是把这个方法延伸到了二维上了。

我们更新的是(x1,y1)到(x2,y2)这个子矩阵的值。

那么我们把

1.(x1,y1)+val.

2.(x1,y2+1)-val;

3.(x2+1,y1)-val;

4.(x2+1,y2+1)+val;

这样我们在计算a[x][y]的值的时候,便是从(1,1)端点加到(x,y)端点的值的和了。

表示看了好多题解也没怎么弄懂,最后自己画图终于搞懂了,问了几个也是迷迷糊糊,实际上树状数组的功能很明确就是上面说的。

这个工具到底干了什么,我想很多写出题解的人也不知道吧,这样是无法举一反三的。也无法很好的使用树状数组这个工具。

#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN=1e5+7;
int n,m,k;
char s[2];
int tu[1005][1005];
int lowbit(int i)
{
    return i&(-i);
}
void add(int x,int y,int d)
{
    for(int i=x; i<=n; i+=lowbit(i))
        for(int j=y; j<=n; j+=lowbit(j))tu[i][j]+=d;
}
int ask(int x,int y)
{
    int sum=0;
    for(int i=x; i>0; i-=lowbit(i))
        for(int j=y; j>0; j-=lowbit(j))sum+=tu[i][j];
        return sum;
}
int main()
{
    int t;
    scanf("%d",&t);
    int x1,y1,x2,y2;
    while(t--)
    {
        memset(tu,0,sizeof(tu));
        scanf("%d%d",&n,&m);
        while(m--)
        {
            scanf("%s",s);
            if(s[0]=='C')
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                add(x1,y1,1);
                add(x1,y2+1,-1);
                add(x2+1,y1,-1);
                add(x2+1,y2+1,1);
            }
            else
            {
                scanf("%d%d",&x2,&y2);
                int ans=ask(x2,y2);
                printf("%d\n",ans%2);
            }
        }
        if(t)puts("");
    }
    return 0;
}




Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值