题目链接

Description

桌子上有2n 堆石子,编号为1..2n。将第2k-1 堆与第2k 堆(1 ≤ k ≤ n)为同一组。第i堆的石子个数用一个正整数Si表示。一次分割操作指的是,从桌子上任取一堆石子,将其移走。然后分割它同一组的另一堆石子,从中取出若干个石子放在被移走的位置,组成新的一堆。操作完成后,所有堆的石子数必须保证大于0。显然,被分割的一堆的石子数至少要为2。两个人轮流进行分割操作。如果轮到某人进行操作时,所有堆的石子数均为1,则此时没有石子可以操作,判此人输掉比赛。

例如,假设初始时桌子上有4 堆石子,数量分别为1,2,3,1。小E可以选择移走第1堆,然后将第2堆分割(只能分出1 个石子)。接下来,小W 只能选择移走第4 堆,然后将第3 堆分割为1 和2。最后轮到小E,他只能移走后两堆中数量为1 的一堆,将另一堆分割为1 和1。这样,轮到小W 时,所有堆的数量均为1,则他输掉了比赛。故小E 存在必胜策略。

Input

的第一行是一个正整数T(T ≤ 20),表示测试数据数量。接下来有T组数据。对于每组数据,第一行是一个正整数N,表示桌子上共有N堆石子。其中,输入数据保证N是偶数。第二行有N个正整数S1..SN,分别表示每一堆的石子数。

Output

包含T 行。对于每组数据,如果小E 必胜,则输出一行”YES”,否则输出”NO”。

Sample Input

2
4
1 2 3 1
6
1 1 1 1 1 1

Sample Output

YES
NO

思路

\((x,y)\)可以从\((1,x-1),(2,x-2),...,(x-1,1),(1,y-1),(2,y-2),...,(y-1,1)\)转移而来

据此打个\(SG\)函数的表,然后找规律

前20行20列如下表

0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 4 0 1 0 2
1 1 2 2 1 1 3 3 1 1 2 2 1 1 4 4 1 1 2 2
0 2 0 2 0 3 0 3 0 2 0 2 0 4 0 4 0 2 0 2
2 2 2 2 3 3 3 3 2 2 2 2 4 4 4 4 2 2 2 2
0 1 0 3 0 1 0 3 0 1 0 4 0 1 0 4 0 1 0 3
1 1 3 3 1 1 3 3 1 1 4 4 1 1 4 4 1 1 3 3
0 3 0 3 0 3 0 3 0 4 0 4 0 4 0 4 0 3 0 3
3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 3 3 3 3
0 1 0 2 0 1 0 4 0 1 0 2 0 1 0 4 0 1 0 2
1 1 2 2 1 1 4 4 1 1 2 2 1 1 4 4 1 1 2 2
0 2 0 2 0 4 0 4 0 2 0 2 0 4 0 4 0 2 0 2
2 2 2 2 4 4 4 4 2 2 2 2 4 4 4 4 2 2 2 2
0 1 0 4 0 1 0 4 0 1 0 4 0 1 0 4 0 1 0 5
1 1 4 4 1 1 4 4 1 1 4 4 1 1 4 4 1 1 5 5
0 4 0 4 0 4 0 4 0 4 0 4 0 4 0 4 0 5 0 5
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 5 5 5 5
0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 5 0 1 0 2
1 1 2 2 1 1 3 3 1 1 2 2 1 1 5 5 1 1 2 2
0 2 0 2 0 3 0 3 0 2 0 2 0 5 0 5 0 2 0 2
2 2 2 2 3 3 3 3 2 2 2 2 5 5 5 5 2 2 2 2

发现$$sg[i][j]=k\rightarrow (i-1)%2{k+1}\lt2k,(j-1)%2{k+1}\lt2k$$

于是算\(sg\)值可以直接从小往大枚举幂次\(k\),符合条件就停。

时间复杂度\(O(1)\).

// 着实要锻炼眼力啊

Code

#include <bits/stdc++.h>
#define maxn 20
#define maxk 33
using namespace std;
typedef long long LL;
int sg[maxn+10][maxn+10];
bool vis[maxn+10];
void work() {
int n;
scanf("%d", &n);
n >>= 1;
int res = 0;
for (int i = 0; i < n; ++i) {
LL x, y;
scanf("%lld%lld", &x, &y);
--x; --y;
LL modd = 2, ans = 0;
for (int k = 0; k <= maxk; ++k) {
if (x % modd < (modd>>1) && y % modd < (modd>>1)) break;
modd <<= 1; ++ans;
}
res ^= ans;
}
puts(res ? "YES" : "NO");
}
void init() {
sg[1][1] = 0;
for (int i = 1; i <= maxn; ++i) {
for (int j = 1; j <= i; ++j) {
if (i==1&&j==1) continue;
memset(vis, 0, sizeof vis);
for (int k = 1; k < i; ++k) vis[sg[k][i-k]] = true;
for (int k = 1; k < j; ++k) vis[sg[k][j-k]] = true;
for (int k = 0; k <= maxn; ++k) if (!vis[k]) { sg[i][j] = sg[j][i] = k; break; }
}
}
// for (int i = 1; i <= maxn; ++i) {
// for (int j = 1; j <= maxn; ++j) printf("%d ", sg[i][j]); putchar('\n');
// }
}
int main() {
// freopen("out.txt", "w", stdout);
// init();
int T;
scanf("%d", &T);
while (T--) work();
return 0;
}

bzoj 1228 [SDOI2009]E&D SG函数打表 找规律的更多相关文章

  1. hdu 3032 Nim or not Nim? (sg函数打表找规律)

    题意:有N堆石子,每堆有s[i]个,Alice和Bob两人轮流取石子,可以从一堆中取任意多的石子,也可以把一堆石子分成两小堆 Alice先取,问谁能获胜 思路:首先观察这道题的数据范围  1 ≤ N ...

  2. Light OJ 1296:Again Stone Game(SG函数打表找规律)

    Alice and Bob are playing a stone game. Initially there are n piles of stones and each pile contains ...

  3. Playing With Stones UVALive - 5059 Nim SG函数 打表找规律

    Code: #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; ll ...

  4. 【博弈论】【SG函数】【找规律】Divide by Zero 2017 and Codeforces Round #399 (Div. 1 + Div. 2, combined) E. Game of Stones

    打表找规律即可. 1,1,2,2,2,3,3,3,3,4,4,4,4,4... 注意打表的时候,sg值不只与剩下的石子数有关,也和之前取走的方案有关. //#include<cstdio> ...

  5. BZOJ 1228: [SDOI2009]E&D(SG定理)

    这道嘛,很容易就看出是个nim和,然后问题就是怎么算子问题的sg函数了 先暴力个表看下规律,很容易就找出来了~~~(百度空间又渣了,图贴不出来= =) 32 0 1 0 2 0 1 0 3 0 1 0 ...

  6. 【博弈论】【SG函数】【找规律】Gym - 101147A - The game of Osho

    以后这种题还是不能空想,必须打个表看看,规律还是比较好找的……具体是啥看代码.用SG函数暴力的部分就不放了. #include<cstdio> using namespace std; i ...

  7. Nim or not Nim? hdu3032 SG值打表找规律

    Nim or not Nim? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  8. Educational Codeforces Round 68 (Rated for Div. 2)D(SG函数打表,找规律)

    #include<bits/stdc++.h>using namespace std;int sg[1007];int main(){ int t; cin>>t; while ...

  9. hdu 2147 SG函数打表(手写也可以) 找规律

    kiki's game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 40000/1000 K (Java/Others) Total ...

随机推荐

  1. 重置 nexus3 admin 密码

    2 简单 3 重构,变化很大 如何处理nexus3忘记admin密码 - CSDN博客 https://blog.csdn.net/tianya6607/article/details/5330562 ...

  2. Mysql主从数据同步cheksum问题

    做主从同步时出现问题,show slave status显示错误: Last_IO_Error: Got fatal error from master when reading data from ...

  3. day 52 Django基础一之web框架的本质

    Django基础一之web框架的本质   django第一天 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于D ...

  4. windows7下将Cygwin加入右键菜单,并从当前目录打开

    第一步:修改windows注册表 1·开始->运行(或者win键+R),输入REGEDIT,回车,打开注册表编辑器: 2·找到HKEY_CLASSES_ROOT\Directory\Backgr ...

  5. BFS:CF356C-Compartments

    C. Compartments time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  6. 关于欧几里德算法(gcd)的证明

    求a,b的最大公约数我们经常用欧几里得算法解决,也称辗转相除法, 代码很简短, int gcd(int a,int b){ return (b==0)?a:gcd(b,a%b); } 但其中的道理却很 ...

  7. Java的内存回收

    一.java引用的种类 1.对象在内存中的状态 可达状态:当一个对象被创建后,有一个以上的引用变量指向它. 可恢复状态: 不可达状态:当对象的所有关联被切断,且系统调用所有对象的finalize方法依 ...

  8. Python linecache模块

    Table of Contents 1. linecache 1.1. 其它 2. 参考资料 linecache 今天分享一个python的小模块: linecache, 可以用它方便地获取某一文件某 ...

  9. 如何排查Java内存泄漏?看完我给跪了!

    没有经验的程序员经常认为Java的自动垃圾回收完全使他们免于担心内存管理.这是一个常见的误解:虽然垃圾收集器做得很好,但即使是最好的程序员也完全有可能成为严重破坏内存泄漏的牺牲品.让我解释一下. 当不 ...

  10. mysql插入、修改、删除

    联合查询: union:合并.联合,将多次查询结果合并成一个结果 语法: 查询语句1: union[all] 查询语句2: union [all] ... 意义 1.将一条比较复杂的查询语句可拆分成多 ...