您的位置:首页 > 其它

bestcoder #56 div 2 C Clarke and puzzle (nim游戏 树状数组)

2015-09-22 11:32 549 查看

Clarke and puzzle

Accepts: 129Submissions: 322Time Limit: 4000/2000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)问题描述
克拉克是一名人格分裂患者。某一天,有两个克拉克(aa和bb)在玩一个方格游戏。
这个方格是一个n*mn∗m的矩阵,每个格子里有一个数c_{i, j}c​i,j​​。
aa想开挂,想知道如何打败bb。
他们要玩qq次游戏,每一次做一次操作:
1. 取出当中的一个子矩阵(x_1, y_1)-(x_2, y_2)(x​1​​,y​1​​)−(x​2​​,y​2​​)玩游戏。两个人轮流行动,每一次只能从这个子矩阵中的一个方格c_{i, j}c​i,j​​中减掉一个的数d(1 \le d \le c_{i, j})d(1≤d≤c​i,j​​),当一个格子的数为00时则不能减。如果操作完后另一者无法操作,那么胜利。否则失败。现在aa作为先手,想知道是否存在一种方案使得自己胜利。
2. 将c_{i, j}c​i,j​​的数改成bb

输入描述
第一行一个整数T(1 \le T \le 5)T(1≤T≤5),表示数据的组数。
每组数据第一行为三个整数n, m, q(1 \le n, m \le 500, 1 \le q \le 2*10^5)n,m,q(1≤n,m≤500,1≤q≤2∗10​5​​)。
接下来是一个nn行mm列的矩阵,其中第ii行第jj列的数为c_{i, j}(0 \le c_{i, j} \le 10^9)c​i,j​​(0≤c​i,j​​≤10​9​​)。
接下来时qq行,第一个数为optopt。当opt=1opt=1时,后面接着四个整数,依次表示x_1, y_1, x_2, y_2(1 \le x_1 \le x_2 \le n, 1 \le y_1 \le y_2 \le m)x​1​​,y​1​​,x​2​​,y​2​​(1≤x​1​​≤x​2​​≤n,1≤y​1​​≤y​2​​≤m),表示一个询问;当opt=2opt=2时,后面接着三个整数x, y, z(1 \le x \le n, 1 \le y \le m, 0 \le z \le 10^9)x,y,z(1≤x≤n,1≤y≤m,0≤z≤10​9​​),表示将c_{x, y}c​x,y​​更改为zz。

输出描述
对于每组数据,每个询问输出aa是否能胜利,如果能,输出YesYes,否则输出NoNo。

输入样例
1
1 2 3
1 2
1 1 1 1 2
2 1 2 1
1 1 1 1 2

输出样例
Yes
No

Hint
第一个询问:一开始aa可以在(1, 2)(1,2)的格子上减掉11,则接下来无论bb怎么选,都还剩一个11,所以aa胜利。
第二个询问:无论aa怎么选,都还剩下一个11,所以bb胜利。

比赛的时候没过.还以为是树状数组写残了.
但实际上是有自己不知道的东西.
这种博弈叫 nim游戏
所以这是一个二维的nim游戏.
nim游戏的性质是xor 和为0必败,否则必胜.
xor和也有前缀和性质,所以可以用树状数组维护.
/*************************************************************************
> File Name: code/bc/#56/r1003.cpp
> Author: 111qqz
> Email: rkz2013@126.com
> Created Time: 2015年09月22日 星期二 11时10分06秒
************************************************************************/

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<stack>
#include<cctype>
#define y1 hust111qqz
#define yn hez111qqz
#define j1 cute111qqz
#define ms(a,x) memset(a,x,sizeof(a))
#define lr dying111qqz
using namespace std;
#define For(i, n) for (int i=0;i<int(n);++i)
typedef long long LL;
typedef double DB;
const int inf = 0x3f3f3f3f;
const int N=5E2+5;
int c

;
int a

;
int n,m,q;
int lowbit ( int x)
{
return x&(-x);
}
void update (int x,int y,int delta)
{
for ( int i = x ; i <= n ; i = i + lowbit(i))
{
for ( int j =  y ;  j <= m ; j = j + lowbit(j))
{
c[i][j]^=delta;
}
}
}

int sum( int x,int y)
{
int res = 0;
for ( int i = x; i >= 1 ; i = i - lowbit(i))
{
for ( int j = y ; j >= 1 ; j = j - lowbit(j))
{
res ^= c[i][j];
}
}
return res;
}
int main()
{
#ifndef  ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif

int T;
scanf("%d",&T);
while (T--)
{
ms(c,0);

scanf("%d %d %d",&n,&m,&q);
for ( int i = 1 ; i <= n ; i++)
{
for ( int j = 1 ; j <= m ; j++)
{
scanf("%d",&a[i][j]);
update (i,j,a[i][j]);
}
}

for (int  i = 0 ; i < q ; i++)
{
int opt;
scanf("%d",&opt);
if (opt==1)
{
int x1,x2,y1,y2;
scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
int tmp = sum(x2,y2)^sum(x2,y1-1)^sum(x1-1,y2)^sum(x1-1,y1-1);
if (tmp>0)
{
puts("Yes");
}
else
{
puts("No");
}
}
else
{
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
update (x,y,a[x][y]); //清零
a[x][y] = z;
update (x,y,a[x][y]);
}
}
}

#ifndef ONLINE_JUDGE
fclose(stdin);
#endif
return 0;
}
View Code

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: