CodeForces 341D

题目大意:

   两种操作:

       Query(x0,y0,x1,y1) 将以(x0,y0)与(x1,y1)为顶点的矩形区域^val

       Update(x0,y0,x1,y1)将以(x0,y0)与(x1,y1)为顶点的矩形区域求^和

解决方法:

   先考虑一维的情况,如果现在不是在二维的情况,现在是在一维的情况,我们应该怎么做呢?

   建立一个二维树状数组,对于修改操作[x,y]我们执行两种操作,第一种add(x,v),第二种add(y+1,v) 但是现在是^,而不是相加,所以呢,我们就建立两个树状数组,如果x是奇数这修改第一个树状数组,否则修改第二个树状数组。因为如果处于x与y之间是,判断与x的奇偶性如果相同就为1,否者就为0,而查询的时候我们也正是这样,如果x是奇数,修改第一个,查询奇数项也是查询第一个,当询问大于y的时候,如果x与y+1奇偶性相同,一共修改偶数项,修改在同一个树状数组中,对后面没有影响。

    现在扩展到二维,也是一样的只不过现在是建立4个树状数组而已。

我的代码:

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
long long tree[2][2][1200][1200];
int n,m;
int add(int x,int y,int v){
  for (int i=x;i<=n;i+=i&(-i))
    for (int j=y;j<=n;j+=j&(-j))
      tree[x&1][y&1][i][j]^=v;
  return 0;
}
long long sum(int x,int y){
  long long ans=0;
  for (int i=x;i>0;i-=i&(-i))
    for (int j=y;j>0;j-=j&(-j))
      ans^=tree[x&1][y&1][i][j];
  return ans;
}
int main(){
  //freopen("test.in","r",stdin);
  while (~scanf("%d%d",&n,&m)){
    for (int i=1;i<=m;i++){
        int op;scanf("%d",&op);
        int x1,y1,x2,y2;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        if (op==2){
            long long val;cin>>val;
            add(x2+1,y2+1,val);
            add(x1,y2+1,val);
            add(x2+1,y1,val);
            add(x1,y1,val);
        }
        else {
            long long ans=0;
            ans^=sum(x2,y2);
            if (x1>1) ans^=sum(x1-1,y2);
            if (y1>1) ans^=sum(x2,y1-1);
            if (x1>1&&y1>1) ans^=sum(x1-1,y1-1);
            cout<<ans<<endl;
        }
    }
  }
  return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值