CF 341D - Iahub and Xors(二维树状数组)

题意:给出一个n×n的矩阵,最开始所有位置的值都为0,有两种操作,一种是将某个矩形区域的值异或v,另一种是求一个矩形区域的异或和。

思路:想办法维护(1,1)(x,y)的异或和,那么矩形区域的异或和就可以根据四个位置的异或和求出。由于异或操作比较特殊,在一个区域进行异或操作,那么这个区域的某个点的(1,1)(x,y)的异或和要么要异或上v,要么异或上0。这样,我们就可以利用二维树状数组,只进行单点更新就完成更新矩形区域的操作,另外,由于区域是否被更新跟奇偶性有关,因此跟据奇偶性来维护4种情况的树状数组。

代码:

#include <iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn=1000+10;
ll C[4][maxn][maxn];
inline int lowbit(int x)
{
    return x&(-x);
}
int getw(int x,int y)
{
    int res=0;
    if(x&1) res+=1;
    if(y&1) res+=2;
    return res;
}
void update(int x,int y,ll v)
{
    int wh=getw(x,y);
    for(int i=x;i<maxn;i+=lowbit(i))
        for(int j=y;j<maxn;j+=lowbit(j))
            C[wh][i][j]^=v;
}
ll query(int x,int y)
{
    int wh=getw(x,y);
    ll res=0;
    for(int i=x;i>0;i-=lowbit(i))
        for(int j=y;j>0;j-=lowbit(j))
            res^=C[wh][i][j];
    return res;
}
int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int n,m;
    memset(C,0,sizeof(C));
    scanf("%d%d",&n,&m);
    int x0,y0,x1,y1,type;
    ll v;
    while(m--)
    {
        scanf("%d",&type);
        scanf("%d%d%d%d",&x0,&y0,&x1,&y1);
        if(type==1)
        {
            ll res=query(x1,y1);
            res^=query(x1,y0-1);
            res^=query(x0-1,y1);
            res^=query(x0-1,y0-1);
            printf("%I64d\n",res);
        }
        else
        {
            scanf("%I64d",&v);
            update(x0,y0,v);
            update(x0,y1+1,v);
            update(x1+1,y0,v);
            update(x1+1,y1+1,v);
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值