Wannafly挑战赛23 T2游戏 SG函数
哎,被卡科技了,想了三个小时,最后还是大佬给我说是\(SG\)函数。
\(SG\)函数,用起来很简单,证明呢?(不可能的,这辈子都是不可能的)
\(SG\)定理
游戏的\(SG\)函数就是各个子游戏的\(SG\)函数的\(Nim-sum\)(就是异或和),比如多堆石子的\(SG\)函数就是所有单堆石子\(SG\)函数的异或和。
\(SG\)函数
首先定义\(mex(T)\)为\(T\)中未出现的自然数中最小的数,其中\(T \subset N\),如\(mex(0,2,3)=1\),\(mex(4,7)=0\)。那么\(SG(x)=mex(S)\),\(S\)为\(x\)的后继状态的\(SG\)函数值集合。
然后,对于某一个状态\(x\),若\(SG(x)=0\),则先手必败,否则先手必胜。
对于这一道题,因为只能拿约数个,也就是至少拿一个,所以我们可以先从小到大预处理一下\(SG\)函数。然后因为我们是先手,要给对手制造一个必败状态,所以只要枚举一下第一步的所有策略,然后判断一下剩下的那些石子的\(SG(x)\)函数的异或和是否为\(0\)就行了。
期望复杂度\(O(n^{\frac{3}{2}})\)。
#include <bits/stdc++.h>
using namespace std;
const int N = 100000;
int n, a[N+5], sum, p, ans, SG[N+5], vis[N+5];
void calc_SG() { //预处理SG函数
SG[0] = 0, SG[1] = 1; //初始化
for(int i = 2; i <= N+1; i++) {
int cnt = 0, t = 0x3f3f3f3f;
for(int j = 1; j*j <= i; j++)
if(i%j == 0) {
vis[++cnt] = SG[i-j];
if(j*j != i) vis[++cnt] = SG[i-i/j];
}
sort(vis+1, vis+cnt+1);
if(vis[1] >= 1) { //计算mex(T)
SG[i] = 0;
continue;
}
for(int j = 1; j <= cnt-1; j++)
if(vis[j+1]-vis[j] > 1) t = min(t, vis[j]+1);
t = min(t, vis[cnt]+1);
SG[i] = t;
}
}
int main() {
ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0); //读入输出加速
cin >> n;
calc_SG(); //预处理SG函数
for(int i = 1; i <= n; i++) cin >> a[i], sum ^= SG[a[i]];
for(int i = 1; i <= n; i++) {
p = sum^SG[a[i]];
for(int j = 1; j*j <= a[i]; j++) {
if(a[i]%j) continue;
if((p^SG[a[i]-j]) == 0) ans++; //判断剩下的Nim-sum是否为0
if(j*j != a[i] && (p^SG[a[i]-a[i]/j]) == 0) ans++;
}
}
cout << ans << endl;
return 0;
}
Wannafly挑战赛23 T2游戏 SG函数的更多相关文章
- 牛客Wannafly挑战赛23 B.游戏
游戏 题目描述 小N和小O在玩游戏.他们面前放了n堆石子,第i堆石子一开始有ci颗石头.他们轮流从某堆石子中取石子,不能不取.最后无法操作的人就输了这个游戏.但他们觉得这样玩太无聊了,更新了一下规则. ...
- 组合游戏 - SG函数和SG定理
在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点 ...
- 题解——牛客网Wannafly挑战赛23 B-游戏 (SG函数)
前言 比赛的时候没学过SG函数的蒟蒻以为是道结论题,但是不是QwQ 和dummyummy巨佬一起推了快三个小时的规律 最后去问了真正的巨佬__stdcall __stdcall面带微笑的告诉我们,这是 ...
- Nowcoder 挑战赛23 B 游戏 ( NIM博弈、SG函数打表 )
题目链接 题意 : 中文题.点链接 分析 : 前置技能是 SG 函数.NIM博弈变形 每次可取石子是约数的情况下.那么就要打出 SG 函数 才可以去通过异或操作判断一个局面的胜负 打 SG 函数的时候 ...
- BZOJ1188 [HNOI2007]分裂游戏(SG函数)
传送门 拿到这道题就知道是典型的博弈论,但是却不知道怎么设计它的SG函数.看了解析一类组合游戏这篇论文之后才知道这道题应该怎么做. 这道题需要奇特的模型转换.即把每一个石子当做一堆石子,且原来在第i堆 ...
- BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏 [Nim游戏 SG函数]
小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如 ...
- BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏(SG函数)
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 871 Solved: 365[Submit][Status][Discuss] Description ...
- HDU 1536 S-Nim (组合游戏+SG函数)
题意:针对Nim博弈,给定上一个集合,然后下面有 m 个询问,每个询问有 x 堆石子 ,问你每次只能从某一个堆中取出 y 个石子,并且这个 y 必须属于给定的集合,问你先手胜还是负. 析:一个很简单的 ...
- BZOJ 1874 取石子游戏 - SG函数
Description $N$堆石子, $M$种取石子的方式, 最后取石子的人赢, 问先手是否必胜 $A_i <= 1000$,$ B_i <= 10$ Solution 由于数据很小, ...
随机推荐
- ButterKnife注解式绑定控件
Butter Knife Android为控件设计的注解绑定库. github地址:https://github.com/JakeWharton/butterknife 添加依赖:(具体看github ...
- Linux Logwatch的学习总结
Logwatch功能介绍 Logwatch是一款Perl脚本编写的.开源的日志分析工具.它能对原始的日志文件进行解析并转换成结构化格式的文档,也能根据您的使用情况和需求来定制报告.Logwatch的特 ...
- 基于TCP 协议的RPC
前言: 环境: windown 10 Eclipse JDK 1.8 RPC的概念: RPC 是远程过程调用,是分布式网站的基础. 实验 SayHelloService.java 接口类,用于规范 S ...
- Apollo的Oracle适配改动
这几天工作需要使用Apollo配置中心.Apollo唯一的依赖是MySQL数据库,然而公司只有Oracle数据库资源.这里有一个Oracle适配改动的分支,但是它是基于0.8.0版本的Apollo.看 ...
- pycharm设置自动换行的方法
只对当前文件有效的操作:菜单栏->View -> Active Editor -> Use Soft Wraps: 如果想对所有文件都有效,就要在setting里面进行操作:File ...
- Asp.Net Core 实现谷歌翻译ApI 免费版
由于谷歌翻译官方API是付费版本,本着免费和开源的精神.分享一下用 Net Core 实现谷歌翻译API的代码. 项目引用的Nuget 包: ChakraCore.NET Newtonsoft.Jso ...
- Asp.Net Core 全局模型验证
public class ActionFilter : IActionFilter { /// <summary> /// action 执行之前 /// </summary> ...
- 日志学习系列(三)——NLog基础知识
前边我们解释了log4net的学习,我们再介绍一下NLog 一.什么是NLog NLog是一个基于.NET平台编写的类库,我们可以使用NLog在应用程序中添加极为完善的跟踪调试代码.NLog是一个简单 ...
- EXTJS的使用
最近一段时间一直使用Extjs作为前端,通过HTTP与.net后端进行交互,今天总结一下EXTJS,方便以后复习. 1.概念: ExtJS可以用来开发RIA也即富客户端的AJAX应用,是一个用java ...
- Python爬虫【解析库之beautifulsoup】
解析库的安装 pip3 install beautifulsoup4 初始化 BeautifulSoup(str,"解析库") from bs4 import BeautifulS ...