题目链接:BZOJ - 1188

题目分析

我们把每一颗石子看做一个单个的游戏,它的 SG 值取决于它的位置。

对于一颗在 i 位置的石子,根据游戏规则,它的后继状态就是枚举符合条件的 j, k。然后后继状态就是 j 与 k 这两个游戏的和。

游戏的和的 SG 值就是几个单一游戏的 SG 值的异或和。

那么还是根据 SG 函数的定义 , 即 SG(u) = mex(SG(v)) ,预处理求出每个位置的 SG 值。一个位置的 SG 值与它后面的位置有关,是取决于它是倒数第几个位置,那么我们预处理求出的 SG[i] 是指倒数第 i 个位置的 SG 值。

还有一个十分重要的性质,我们不需要考虑每个位置上石子的数量,只需要考虑数量的奇偶,因为如果有偶数个石子,那么这个位置的 SG 值会被异或到整个状态的 SG 中共偶数次,就会抵消,相当于没有。

奇数就是相当于偶数 + 1,因此只要异或一次即可。

组合游戏真是有许多神奇的性质Orz。

代码

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath> using namespace std; const int MaxN = 25, N = 21; int T, n, Mark_Index;
int A[MaxN], SG[MaxN], Mark[MaxN * MaxN]; void Prepare_SG() {
Mark_Index = 0;
memset(Mark, 0, sizeof(Mark));
for (int i = 1; i <= N; ++i) {
++Mark_Index;
for (int j = i - 1; j >= 1; --j)
for (int k = j; k >= 1; --k)
Mark[SG[j] ^ SG[k]] = Mark_Index;
for (int j = 0; j <= N * N; ++j) {
if (Mark[j] != Mark_Index) {
SG[i] = j; break;
}
}
}
} int main()
{
scanf("%d", &T);
Prepare_SG();
for (int Case = 1; Case <= T; ++Case) {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", &A[i]);
int Temp = 0, Tot = 0;
for (int i = 1; i <= n; ++i)
if (A[i] & 1) Temp ^= SG[n - i + 1];
for (int i = 1; i <= n; ++i) {
if (A[i] == 0) continue;
for (int j = i + 1; j <= n; ++j) {
for (int k = j; k <= n; ++k) {
if ((Temp ^ SG[n - i + 1] ^ SG[n - j + 1] ^ SG[n - k + 1]) != 0) continue;
++Tot;
if (Tot == 1) printf("%d %d %d\n", i - 1, j - 1, k - 1);
}
}
}
if (Tot == 0) printf("-1 -1 -1\n");
printf("%d\n", Tot);
}
return 0;
}

  

[BZOJ 1188] [HNOI2007] 分裂游戏 【博弈论|SG函数】的更多相关文章

  1. bzoj 1188 [HNOI2007]分裂游戏(SG函数,博弈)

    1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 733  Solved: 451[Submit][Status ...

  2. bzoj1188 [HNOI2007]分裂游戏 博弈论 sg函数的应用

    1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 973  Solved: 599[Submit][Status ...

  3. bzoj 1188 [HNOI2007]分裂游戏 SG函数 SG定理

    [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1394  Solved: 847[Submit][Status][Dis ...

  4. BZOJ 1188: [HNOI2007]分裂游戏(multi-nim)

    Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1386  Solved: 840[Submit][Status][Discuss] Descripti ...

  5. BZOJ 1188 [HNOI2007]分裂游戏

    AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1188 学习SG函数的过程中,我先看了一篇叫做 <2008-贾志豪-组合数学略述... ...

  6. bzoj 1188 : [HNOI2007]分裂游戏 sg函数

    题目链接 给n个位置, 每个位置有一个小球. 现在两个人进行操作, 每次操作可以选择一个位置i, 拿走一个小球.然后在位置j, k(i<j<=k)处放置一个小球. 问你先进行什么操作会先手 ...

  7. BZOJ1188:[HNOI2007]分裂游戏(博弈论)

    Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏.该游戏的规则试:共有n个瓶子,标号为0,1,2.....n-1,第i个瓶子中装有p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择3个 ...

  8. [2016北京集训试题6]魔法游戏-[博弈论-sg函数]

    Description Solution 首先,每个节点上的权值可以等价于该节点上有(它的权的二进制位数+1)个石子,每次可以拿若干个石子但不能不拿. 然后就发现这和NIM游戏很像,就计算sg函数em ...

  9. BZOJ P1188 HNOI2007 分裂游戏——solution

    题目描述: (<--这个) 组合游戏,——把每个石头看做一个游戏, Multi_game——消去i上的石子后,,k上的游戏又多了一个: 于是就套用multi_game的模型即可 求解SG函数时, ...

随机推荐

  1. 将.lib库文件转换成.a库文件的工具

    分享如下两个链接: 微盘: http://vdisk.weibo.com/s/ztzPTJIC52mz2 百度云盘: http://pan.baidu.com/s/11gTOc 使用方法,解压文件mi ...

  2. 使用dom4j解析xml文件,并封装为javabean对象

    dom4j是一个java的XML api,性能优异.功能强大.易于使用.这里使用dom4j对xml文件进行解析,并完成对文件的封装. 实现对xml文件的解析,主要使用到的是dom4j中的SAXRead ...

  3. MySQL 一致性读 深入研究 digdeep博客学习

    http://www.cnblogs.com/digdeep/p/4947694.html 一致性读,又称为快照读.使用的是MVCC机制读取undo中的已经提交的数据.所以它的读取是非阻塞的. 相关文 ...

  4. Note | Javascript权威指南[第六版] 第1章:Javascript概述

       JavaScript是一门高端的.动态的.弱类型的编程语言,非常适合面向对象和函数式的编程风格.JavaScript的语法源自Java,它的一等函数(first-class function)来 ...

  5. 旅行喵 React Native 技术实践

    旅行喵,是一款帮助用户快乐旅行的APP. 第一版的首打功能是行程定制,和景点信息介绍.大家可以在上面做非常简单的偏好选择,通过我们的智能算法生成适合自己的旅行路线. 为什么要用RN呢? 首先,相对于其 ...

  6. Java基础知识强化07:打印出空心菱形

    1.如图打印出空心菱形: 2.下面是逻辑实现代码: package himi.hebao04; import java.util.Scanner; public class TestDemo08 { ...

  7. 设置ViewController 数据源无法改变view

    病情描述: viewController创建的时候勾选了xib,然后在显示的时候调用了如下语句: MTDetailDealViewController *detailController = [[MT ...

  8. sql根据'/'截取最后的字符串

    filpath字段值:/DataFile/UpLoad/Logo/NoPhoto.jpg select filpath,REVERSE((SUBSTRING(REVERSE(FilPath),0,CH ...

  9. Android 通信机制Message、Handler 的用法

    Android中提供了通信机制,Message.Handler 等,Message用于在子线程中传递数据,Handler用于发送数据到主线程中, 下面介绍基于Message.Handler的计时器 i ...

  10. SQL SERVER字符集的研究(中英文字符集,varchar,nvarchar).

    一. 试验归类测试SQL: drop table a )) insert into a values('a') insert into a values(N'a') insert into a val ...