POJ 2155 二维线段树

POJ 2155  二维线段树

思路:二维线段树就是每个节点套一棵线段树的树。

刚开始因为题目是求A[I,J],然后在y查询那直接ans^=Map[i][j]的时候没看懂,后面自己把图画出来了才理解。

因为只有0和1,所以可以用异或来搞,而不需要每次都需要修改。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define llson j<<1,l,mid
#define rrson j<<1|1,mid+1,r
#define INF 510010
#define maxn 4010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
bool Map[maxn][maxn];
int n,q,t,ans;
void update_y(int i,int j,int l,int r,int y1,int y2)
{
    if(l==y1&&r==y2) {Map[i][j]^=1;return ;}
    int mid=(l+r)>>1;
    if(y2<=mid) update_y(i,llson,y1,y2);
    else if(y1>mid) update_y(i,rrson,y1,y2);
    else
    {
        update_y(i,llson,y1,mid);
        update_y(i,rrson,mid+1,y2);
    }
}
void update_x(int i,int l,int r,int x1,int x2,int y1,int y2)
{
    if(l==x1&&r==x2)
    {
        update_y(i,1,1,n,y1,y2);
        return ;
    }
    int mid=(l+r)>>1;
    if(x2<=mid) update_x(lson,x1,x2,y1,y2);
    else if(x1>mid) update_x(rson,x1,x2,y1,y2);
    else
    {
        update_x(lson,x1,mid,y1,y2);
        update_x(rson,mid+1,x2,y1,y2);
    }
}
void query_y(int i,int j,int l,int r,int y)
{
    ans^=Map[i][j];
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(y<=mid) query_y(i,llson,y);
    else query_y(i,rrson,y);
}
void query_x(int i,int l,int r,int x,int y)
{
    query_y(i,1,1,n,y);
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(x<=mid) query_x(lson,x,y);
    else query_x(rson,x,y);
}
int main()
{
    //freopen("test.txt","r",stdin);
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&q);
        mem(Map,0);
        while(q--)
        {
            char s[2];
            scanf("%s",s);
            ans=0;
            if(s[0]=='C')
            {
                int x1,x2,y1,y2;
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                update_x(1,1,n,x1,x2,y1,y2);
            }
            else
            {
                int x,y;
                scanf("%d%d",&x,&y);
                query_x(1,1,n,x,y);
                printf("%d\n",ans);
            }
        }
        if(t) puts("");
    }
    return 0;
}

POJ 2155 二维线段树,布布扣,bubuko.com

时间: 2024-10-12 23:27:07

POJ 2155 二维线段树的相关文章

POJ 2155 二维线段树 经典的记录所有修改再统一遍历 单点查询

本来是想找一个二维线段树涉及懒惰标记的,一看这个题,区间修改,单点查询,以为是懒惰标记,敲到一半发现这二维线段树就不适合懒惰标记,你更新了某段的某列,但其实其他段的相应列也要打标记,但因为区间不一样,又不好打...也可能是我这是在套用一维线段树的思想,还有更好的二维线段树懒惰标记方法 反正到现在我还没搞定二维线段树的懒惰标记,因为这道题不用懒惰标记,因为是二进制序列,区间修改仅限于翻转操作,那就只要记录每次操作,最后查询的时候从上往下把所有修改都来上一遍,就可以了.就类似于树状数组的第二种用法,

POJ 2155 2维线段树 || 2维BIT

#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <vector> #include <map> #include <set> #include <stack> #define mp make_pair #define pa pair<int,int> #define pb p

POJ 2155 Matrix (二维线段树)

http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18143   Accepted: 6813 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. I

POJ 2155 Matrix 二维线段树+标记永久化?

题意:链接 方法:二维线段树+标记永久化 解析:题意是比较明朗的,算一下内存发现4000^2也是可以接受的,于是就开始yy二维线段树? 对于第一层x的线段树,每个节点开一整棵y线段树. 用个二维数组就实现了? 不过发现个问题啊,这题怎么pushdown啊,标记传不下去啊.如果给x打个标记那么怎么知道y传那段啊? 于是就学了新的东西?标记永久化. 本题是单点查询嘛,标记永久化就应该是把相应的区间直接异或,不用往下传?那查询的时候怎么办呢?只需要在查询的时候把所有路过该点的区间都异或起来就OK了.貌

POJ 2155 Matrix【二维线段树】

题目大意:给你一个全是0的N*N矩阵,每次有两种操作:1将矩阵中一个子矩阵置反,2.查询某个点是0还是1 思路:裸的二维线段树 #include<iostream>#include<cstdio>#include <math.h>#include<algorithm>#include<string.h>#include<queue>#define MOD 1000003#define maxn 4009#define LL long

poj 2155 二维树状数组

http://poj.org/problem?id=2155 Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17721   Accepted: 6653 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. I

poj 1195:Mobile phones(二维线段树,矩阵求和,经典题)

Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14391   Accepted: 6685 Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The

[POJ2155] Matrix(二维线段树,树套树)

题目链接:http://poj.org/problem?id=2155 题意:给一个01矩阵,两个操作,翻转:子矩阵里每一个数都由0变1,1变0. 查询:查询某一点是0还是1. 一直以为二维线段树就是开一个线段树数组的我- 这题暴力更新每一个小矩形,翻转就+1,最后看看某点的奇偶. 写屎了,特别注意的是在外层查询的时候要先把当前层的内层query掉,接着再向下扩展.这样外层就不用lazy啦 1 #include <algorithm> 2 #include <iostream> 3

POJ 1195 2维线段树(树套树实现) 树状数组

1: #include <stdio.h> 2: #include <string.h> 3: #include <stdlib.h> 4: #include <algorithm> 5: #include <iostream> 6: using namespace std; 7:   8: #define LL(a) a<<1 9: #define RR(a) a<<1|1 10: const int MaxL = 10