Codeforces Round #198 (Div. 1) D. Iahub and Xors 二维树状数组*

D. Iahub and Xors
 

Iahub does not like background stories, so he'll tell you exactly what this problem asks you for.

You are given a matrix a with n rows and n columns. Initially, all values of the matrix are zeros. Both rows and columns are 1-based, that is rows are numbered 1, 2, ..., n and columns are numbered 1, 2, ..., n. Let's denote an element on the i-th row and j-th column as ai, j.

We will call a submatrix (x0, y0, x1, y1) such elements ai, j for which two inequalities hold: x0 ≤ i ≤ x1, y0 ≤ j ≤ y1.

Write a program to perform two following operations:

  1. Query(x0, y0, x1, y1): print the xor sum of the elements of the submatrix (x0, y0, x1, y1).
  2. Update(x0, y0, x1, y1, v): each element from submatrix (x0, y0, x1, y1) gets xor-ed by value v.
Input

The first line contains two integers: n (1 ≤ n ≤ 1000) and m (1 ≤ m ≤ 105). The number m represents the number of operations you need to perform. Each of the next m lines contains five or six integers, depending on operation type.

If the i-th operation from the input is a query, the first number from i-th line will be 1. It will be followed by four integers x0, y0, x1, y1. If thei-th operation is an update, the first number from the i-th line will be 2. It will be followed by five integers x0, y0, x1, y1, v.

It is guaranteed that for each update operation, the following inequality holds: 0 ≤ v < 262. It is guaranteed that for each operation, the following inequalities hold: 1 ≤ x0 ≤ x1 ≤ n1 ≤ y0 ≤ y1 ≤ n.

Output

For each query operation, output on a new line the result.

Examples
input
3 5
2 1 1 2 2 1
2 1 3 2 3 2
2 3 1 3 3 3
1 2 2 3 3
1 2 2 3 2
output
3
2
Note

After the first 3 operations, the matrix will look like this:


1 1 2
1 1 2
3 3 3

The fourth operation asks us to compute 1 xor 2 xor 3 xor 3 = 3.

The fifth operation asks us to compute 1 xor 3 = 2.

 

题意:

  给你一个n×n的矩阵;初始时所有位置的值都为0;

  m次操作:两种操作,一种是将某个矩形区域的值异或v,另一种是求一个矩形区域的异或和。

题解:

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

#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double Pi = acos(-1.0);
const int N = 1e3+10, M = 1e5+20, mod = 1e9+7, inf = 2e9;

int n,m,mp[N][N];
LL C[4][N][N];

int get(int x,int y) {
        int res = 0;
        if(x&1) res += 1;
        if(y&1) res += 2;
        return res;
}
LL ask(int x,int y) {
        LL s = 0;
        int wh = get(x,y);
         for(int i = x; i; i-= i & (-i))
            for(int j = y; j; j -= j & (-j)) s^=C[wh][i][j];
        return s;
}
void update(int x,int y,LL v) {
        int wh = get(x,y);
        for(int i = x; i < N; i+= i&(-i))
            for(int j = y; j < N; j += j&(-j)) C[wh][i][j] ^= v;
}
int main() {
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= m; ++i) {
        int op,x1,x2,y1,y2;
        LL v;
        scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2);
        if(op == 1) {
           LL a = ask(x2,y2);
           LL b = 0, c = 0, d = 0;
           if(y1 > 1) b = ask(x2,y1-1);
           if(x1 > 1) c = ask(x1-1,y2);
           if(x1 > 1 && y1 > 1) d = ask(x1-1,y1-1);
           printf("%I64d\n",a^b^d^c);
        } else {
            scanf("%I64d",&v);
            update(x2+1,y2+1,v);
            update(x2+1,y1,v);
            update(x1,y2+1,v);
            update(x1,y1,v);
        }
    }
    return 0;
}

 

posted @ 2016-10-22 14:20  meekyan  阅读(234)  评论(0编辑  收藏  举报