[poj 2155] Matrix(二维zkw线段树)

本文介绍了一种使用二维ZKW线段树解决矩阵更新与查询的方法。通过建立ZKW线段树结构,实现了对矩阵的快速更新(翻转矩形区域)和查询(判断坐标点所在位置的值)。代码中包含了主函数、更新和查询操作的实现,以及输入样例的处理。
摘要由CSDN通过智能技术生成

特地说明是zkw线段树,而不是常规线段树,这道题好像故意卡二维线段树,晕啊。
都已经故意卡线段树了,zkw版线段树还是能过(700ms+),这说明zkw版线段树还是非常值得学习的!
这道题各种算法的效率比较:
    常规二维线段树:TLE
    二维zkw线段树:700ms+
    二维树状数组:450ms+

二维zkw线段树的写法:

#include<iostream>
using namespace std;

bool tree[5010][5010];
int M;

void update_y(int x, int y1, int y2)
{
y1 = y1 - 1 + M;
y2 = y2 + 1 + M;
while(y1^y2^1)
{
if(~y1&1)
tree[x][y1^1] = !tree[x][y1^1];
if(y2&1)
tree[x][y2^1] = !tree[x][y2^1];
y1 >>= 1;
y2 >>= 1;
}
}

void update(int x1, int y1, int x2, int y2)
{
x1 = x1 - 1 + M;
x2 = x2 + 1 + M;
while(x1^x2^1)
{
if(~x1&1)
update_y(x1^1, y1, y2);
if(x2&1)
update_y(x2^1, y1, y2);
x1 >>= 1;
x2 >>= 1;
}
}

bool find_y(int x, int y)
{
y += M;
bool re = false;
while(y)
{
if(tree[x][y])
re = !re;
y >>= 1;
}
return re;
}

bool find_x(int x, int y)
{
x += M;
bool re = false;
while(x)
{
re = re ^ find_y(x, y);
x >>= 1;
}
return re;
}

int main()
{
int tot;
int n, m;
char str[5];
int a, b, c, d;
scanf("%d", &tot);
for(int i = 0; i < tot; i++)
{
if(i)putchar(10);
memset(tree, 0, sizeof(tree));
scanf("%d%d", &n, &m);
M = 1;
while(M-2 < n) M <<= 1;
for(int j = 1; j <= m; j++)
{
scanf("%s", str);
if(str[0] == 'C')
{
scanf("%d%d%d%d", &a, &b, &c, &d);
update(a, b, c, d);
}
else if(str[0] == 'Q')
{
scanf("%d%d", &a, &b);
if(find_x(a, b))
printf("1\n");
else
printf("0\n");
}
}
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值