关键词:线段树

二维线段树维护一个 维护一个X线段的线段树,每个X节点维护一个 维护一个Y线段的线段树。

注意,以下代码没有PushDownX。因为如果要这么做,PushDownX时,由于当前X节点的子节点可能存在标记,而标记不能叠加,导致每次PushDownX时都要把子节点PushDownX一次。每次PushDownX都要对子节点UpdateY,代价太高。这种情况下原则是:只有查询操作<<更新操作时才PushDownX。

#include <cstdio>
#include <cstring>
#include <cassert>
#include <vector>
using namespace std; const int MAX_X = , MAX_Y = ; struct RangeTree2d
{
private:
bool Rev[MAX_X * ][MAX_Y * ];
int YlMin, YrMax, XlMin, XrMax; void PushDownY(int xCur, int yCur)
{
if (Rev[xCur][yCur])
{
Rev[xCur][yCur * ] ^= ;
Rev[xCur][yCur * + ] ^= ;
Rev[xCur][yCur] = false;
}
} void UpdateY(int xCur, int yCur, int sl, int sr, int al, int ar)
{
assert(sl <= sr&&al <= ar&&al <= sr&&ar >= sl);
if (al <= sl&&sr <= ar)
{
Rev[xCur][yCur] ^= ;
return;
}
int mid = (sr - sl) / + sl;
if (al <= mid)
UpdateY(xCur, yCur * , sl, mid, al, ar);
if (ar > mid)
UpdateY(xCur, yCur * + , mid + , sr, al, ar);
} void UpdateY(int xCur, int l, int r)
{
UpdateY(xCur, , YlMin, YrMax, l, r);
} bool QueryY(int xCur, int yCur, int l, int r, int y)
{
if (l == r)
return Rev[xCur][yCur];
PushDownY(xCur, yCur);
int mid = (l + r) / ;
if (y <= mid)
return QueryY(xCur, yCur * , l, mid, y);
else
return QueryY(xCur, yCur * + , mid + , r, y);
} bool QueryY(int xCur, int y)
{
return QueryY(xCur, , YlMin, YrMax, y);
} void UpdateX(int xCur, int sl, int sr, int al, int ar, int yl, int yr)
{
//printf("C x:sl %d sr %d al %d ar %d\n", sl, sr, al, ar);
assert(sl <= sr&&al <= ar&&al <= sr&&ar >= sl);
if (al <= sl&&sr <= ar)
{
UpdateY(xCur, yl, yr);
return;
}
int mid = (sr - sl) / + sl;
if (al <= mid)
UpdateX(xCur * , sl, mid, al, ar, yl, yr);
if (ar > mid)
UpdateX(xCur * + , mid + , sr, al, ar, yl, yr);
} void QueryX(int xCur, int l, int r, int x, int y, bool &ans)
{
ans ^= QueryY(xCur, y);
if (l == r)
return;
int mid = (l + r) / ;
if (x <= mid)
QueryX(xCur * , l, mid, x, y, ans);
else
QueryX(xCur * + , mid + , r, x, y, ans);
} public:
void Init(int xlMin, int xrMax, int ylMin, int yrMax)
{
XlMin = xlMin;
XrMax = xrMax;
YlMin = ylMin;
YrMax = yrMax;
memset(Rev, false, sizeof(Rev));
} void Update(int xl, int xr, int yl, int yr)
{
UpdateX(, XlMin, XrMax, xl, xr, yl, yr);
} int Query(int x, int y)
{
bool ans = false;
QueryX(, XlMin, XrMax, x, y, ans);
return ans;
}
}g; int main()
{
#ifdef _DEBUG
freopen("c:\\noi\\source\\input.txt", "r", stdin);
#endif
int totCase;
scanf("%d", &totCase);
while (totCase--)
{
int mSize, qCnt;
scanf("%d%d", &mSize, &qCnt);
g.Init(, mSize, , mSize);
while (qCnt--)
{
char op;
int x1, x2, y1, y2;
scanf("\n%c", &op);
switch (op)
{
case 'C':
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
g.Update(x1, x2, y1, y2);
break;
case 'Q':
scanf("%d%d", &x1, &y1);
printf("%d\n", g.Query(x1, y1));
break;
default:
assert();
}
}
printf("\n");
}
return ;
}

反思:

1.不用动态开点,因为内存够。动态申请内存费时间。

2.不要将问题扩大化为求区域面积,提高了编程复杂度。

POJ2155 Matrix 二维线段树的更多相关文章

  1. POJ2155 Matrix二维线段树经典题

    题目链接 二维树状数组 #include<iostream> #include<math.h> #include<algorithm> #include<st ...

  2. POJ 2155 Matrix (二维线段树入门,成段更新,单点查询 / 二维树状数组,区间更新,单点查询)

    题意: 有一个n*n的矩阵,初始化全部为0.有2中操作: 1.给一个子矩阵,将这个子矩阵里面所有的0变成1,1变成0:2.询问某点的值 方法一:二维线段树 参考链接: http://blog.csdn ...

  3. poj 2155 matrix 二维线段树 线段树套线段树

    题意 一个$n*n$矩阵,初始全为0,每次翻转一个子矩阵,然后单点查找 题解 任意一种能维护二维平面的数据结构都可以 我这里写的是二维线段树,因为四分树的写法复杂度可能会退化,因此考虑用树套树实现二维 ...

  4. poj 2155 matrix 二维线段树

    题目链接 区间翻转, 单点查询, 查询操作我真是不太明白...... #include <iostream> #include <vector> #include <cs ...

  5. POJ2155 Matrix 【二维线段树】

    题目链接 POJ2155 题解 二维线段树水题,蒟蒻本想拿来养生一下 数据结构真的是有毒啊,, TM这题卡常 动态开点线段树会TLE[也不知道为什么] 直接开个二维数组反倒能过 #include< ...

  6. POJ 2155 Matrix (二维线段树)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17226   Accepted: 6461 Descripti ...

  7. poj 2155:Matrix(二维线段树,矩阵取反,好题)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17880   Accepted: 6709 Descripti ...

  8. [poj2155]Matrix(二维树状数组)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 25004   Accepted: 9261 Descripti ...

  9. ZOJ 1859 Matrix Searching(二维线段树)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1859 Matrix Searching Time Limit: 10 Seco ...

随机推荐

  1. POJ 3581 Sequence ——后缀数组 最小表示法

    [题目分析] 一见到题目,就有了一个显而易见obviously的想法.只需要每次找到倒过来最小的那一个字符串翻转就可以了. 然而事情并不是这样的,比如说505023这样一个字符串,如果翻转了成为320 ...

  2. NIO Channel的学习笔记总结

    摘自:http://blog.csdn.net/tsyj810883979/article/details/6876603 1.1  非阻塞模式 Java  NIO非堵塞应用通常适用用在I/O读写等方 ...

  3. bzoj3743 [Coci2015]Kamp 常州模拟赛d6t2

    3743: [Coci2015]Kamp Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 484  Solved: 229[Submit][Status ...

  4. Spring-IOC源码解读3-依赖注入

    当容器已经载入了BeanDefinition的信息完成了初始化,我们继续分析依赖注入的原理,需要注意的是依赖注入是用户第一次向IOC容器获取Bean的时候发生的,这里有个例外,那就是如果用户在Bean ...

  5. uva 11995 判别数据类型

    Problem I I Can Guess the Data Structure! There is a bag-like data structure, supporting two operati ...

  6. 2017 ACM/ICPC 广西邀请赛 题解

    题目链接  Problems HDOJ上的题目顺序可能和现场比赛的题目顺序不一样, 我这里的是按照HDOJ的题目顺序来写的. Problem 1001 签到 #include <bits/std ...

  7. 8.Java web—JSP基本语法

    1)脚本标识 <%-- <%@这两都之间不能为空格 ,但page前面可以任意空格 --%> <%@ page language="java" content ...

  8. SystemTap 静态探针安装包

     yum install systemtap-sdt-devel 

  9. memcache的学习路线图

     memcache学习材料 //memcache自带的github 上的 wiki     //席剑飞 Memcache(MC)系列 1~8系列 评注: memcache系统写的最深的一博客,建议一读 ...

  10. 总结下JavaWeb应用里正确显示中文需要的设置

    1.前台页面需要加的设置: <%@ page contentType="text/html; charset=UTF-8"%> html标签后加上<meta ht ...