hdu 5465 (树状数组 + 博弈)

题意:基于矩阵的NIM游戏,求异或和。

思路:在x1,y1 到 x2, y2的异或和 =  A[ x2 ][ y2 ] ^ A[x1-1][ y2 ] ^ A[ x2 ][y1 - 1] ^ A[ x1-1 ][ y1 - 1 ]

先普通来了两次,结果都超时。  上个二维树状数组AC


#include <cstdio>
#include <cstring>
#define MAXN 100010
using namespace std;

int a[505][505];
int sum[505][505];
int n,m,qq;

int lowbit(int x)
{
    return x&(-x);
}

void inser(int x,int y,int k)
{
    for(int i = x; i <= n; i+=lowbit(i))
        for(int j = y; j <= m; j+=lowbit(j))
        {
            sum[i][j] ^= k;
        }
}

int query(int x,int y)
{
    int ans = 0;
    for(int i = x; i >= 1; i-=lowbit(i))
        for(int j = y; j >= 1; j-=lowbit(j))
        {
            ans ^= sum[i][j];
        }
    return ans;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int q;
        scanf("%d%d%d",&n,&m,&q);
        memset(sum,0,sizeof(sum));
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
            {
                scanf("%d",&a[i][j]);
                inser(i,j,a[i][j]);
            }
        for(int i = 1; i <= q; i++)
        {
            int qq,x1,y1,x2,y2,tt;
            scanf("%d",&qq);
            if(qq == 1)
            {
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                int ans = 0;
                ans ^= query(x2, y2);
                if(y1 > 1) ans ^= query(x2, y1 - 1);
                if(x1 > 1) ans ^= query(x1 - 1, y2);
                if(x1 > 1 && y1 > 1) ans ^= query(x1 - 1, y1 - 1);
                if(ans)
                    printf("Yes
");
                else
                    printf("No
");
            }
            else
            {
                scanf("%d%d%d",&x1,&y1,&tt);
                inser(x1,y1,a[x1][y1]^tt);
                a[x1][y1] = tt;
            }
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Przz/p/5409746.html