[HAOI2015] 数组游戏 - 博弈论,SG函数

有一个长度为N的数组,甲乙两人在上面进行这样一个游戏:首先,数组上有一些格子是白的,有一些是黑的。然后两人轮流进行操作。每次操作选择一个白色的格子,假设它的下标为x。接着,选择一个大小在1~n/x之间的整数k,然后将下标为x、2x、...、kx的格子都进行颜色翻转。不能操作的人输。现在甲(先手)有一些询问。每次他会给你一个数组的初始状态,你要求出对于这种初始状态他是否有必胜策略。

Solution

用暴力 SG 打个表,发现一段一段的 SG 值都是相同的,所以套个整除分块即可

#include <bits/stdc++.h>
using namespace std;

const int N = 400005;
int n,q,lim,sg[2][N],pos[N],u[N];

int SG(int x) {
    x=n/(n/x);
    if(x>lim) return sg[1][n/x];
    else return sg[0][x];
}

void presolve() {
    int cnt=0;
    for(int i=1,j;i<=n;i=j+1) {
        j=n/(n/i);
        pos[++cnt]=j;
    }
    while(cnt) {
        int x=pos[cnt], now=0, mex=1;
        u[now]=cnt;
        for(int i=x+x,j;i<=n;i=j+x) {
            j=n/(n/i)/x*x;
            u[now^SG(j)]=cnt;
            if((j-i)/x&1^1) now^=SG(j);
        }
        while(u[mex]==cnt) ++mex;
        if(x>lim) sg[1][n/x]=mex;
        else sg[0][x]=mex;
        --cnt;
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin>>n>>q;
    lim=sqrt(n);
    presolve();
    while(q--) {
        int m,x,ans=0;
        cin>>m;
        while(m--) {
            cin>>x;
            ans^=SG(x);
        }
        if(ans) cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
}

原文地址:https://www.cnblogs.com/mollnn/p/12400733.html

时间: 2024-11-06 08:25:32

[HAOI2015] 数组游戏 - 博弈论,SG函数的相关文章

【BZOJ 4035】 4035: [HAOI2015]数组游戏 (博弈)

4035: [HAOI2015]数组游戏 Time Limit: 15 Sec  Memory Limit: 32 MBSubmit: 181  Solved: 89 Description 有一个长度为N的数组,甲乙两人在上面进行这样一个游戏:首先,数组上有一些格子是白的,有一些是黑的.然 后两人轮流进行操作.每次操作选择一个白色的格子,假设它的下标为x.接着,选择一个大小在1~n/x之间的整数 k,然后将下标为x.2x.....kx的格子都进行颜色翻转.不能操作的人输.现在甲(先手)有一些询

Nim 游戏、SG 函数、游戏的和

Nim游戏 Nim游戏定义 Nim游戏是组合游戏(Combinatorial Games)的一种,准确来说,属于"Impartial Combinatorial Games"(以下简称ICG).满足以下条件的游戏是ICG(可能不太严谨):1.有两名选手:2.两名选手交替对游戏进行移动(move),每次一步,选手可以在(一般而言)有限的合法移动集合中任选一种进行移动:3.对于游戏的任何一种可能的局面,合法的移动集合只取决于这个局面本身,不取决于轮到哪名选手操作.以前的任何操作.骰子的点数

bzoj 1874 取石子游戏 题解 &amp; SG函数初探

[原题] 1874: [BeiJing2009 WinterCamp]取石子游戏 Time Limit: 5 Sec  Memory Limit: 162 MB Submit: 334  Solved: 122 [Submit][Status] Description 小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如果有,第一步如何取石子. In

[BZOJ 1874] [BeiJing2009 WinterCamp] 取石子游戏 【博弈论 | SG函数】

题目链接:BZOJ - 1874 题目分析 这个是一种组合游戏,是许多单个SG游戏的和. 就是指,总的游戏由许多单个SG游戏组合而成,每个SG游戏(也就是每一堆石子)之间互不干扰,每次从所有的单个游戏中选一个进行决策,如果所有单个游戏都无法决策,游戏失败. 有一个结论,SG(A + B + C ... ) = SG(A)^SG(B)^SG(C) ... 这道题每堆石子不超过 1000 , 所以可以把 [0, 1000] 的 SG 值暴力求出来,使用最原始的 SG 函数的定义, SG(u) = m

[BZOJ 1188] [HNOI2007] 分裂游戏 【博弈论|SG函数】

题目链接:BZOJ - 1188 题目分析 我们把每一颗石子看做一个单个的游戏,它的 SG 值取决于它的位置. 对于一颗在 i 位置的石子,根据游戏规则,它的后继状态就是枚举符合条件的 j, k.然后后继状态就是 j 与 k 这两个游戏的和. 游戏的和的 SG 值就是几个单一游戏的 SG 值的异或和. 那么还是根据 SG 函数的定义 , 即 SG(u) = mex(SG(v)) ,预处理求出每个位置的 SG 值.一个位置的 SG 值与它后面的位置有关,是取决于它是倒数第几个位置,那么我们预处理求

POJ 2425 A Chess Game 博弈论 sg函数

http://poj.org/problem?id=2425 典型的sg函数,建图搜sg函数预处理之后直接求每次游戏的异或和.仍然是因为看不懂题目卡了好久. 这道题大概有两个坑, 1.是搜索的时候vis数组应该在函数内声明(似乎这是我经常在搜索里犯的错误,为了省一点空间整道题都写错了): 2.是n个点的有向无环图边数上限是n^2(re了好久QAQ). 在漫长的查资料过程之后终于大概搞懂了sg函数的原理,愉快.下一篇大概会写一个小结. 代码 1 #include<cstdio> 2 #inclu

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

1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 733  Solved: 451[Submit][Status][Discuss] Description 聪 聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子.标号为 i,j,k, 并要保证 i < j ,

2016多校联合训练1 B题Chess (博弈论 SG函数)

题目大意:一个n(n<=1000)行,20列的棋盘上有一些棋子,两个人下棋,每回合可以把任意一个棋子向右移动到这一行的离这个棋子最近的空格上(注意这里不一定是移动最后一个棋子),不能移动到棋盘外,不能移动了就算输,两个人都用最优策略,问先手是否有必胜策略. 这题显然就是SG函数了吧.行与行之间互不影响,所以可以看成n个子游戏,求出它们各自的SG函数然后异或一下就可以了.我们发现只有20列,2^21=2097152,所以我们可以先把行的所有情况的SG函数预处理出来,然后每次询问O(1)就行了. 代

[HAOI2015]数组游戏

https://zybuluo.com/ysner/note/1233363 题面 有一个长度为\(N\)的数组,每个格子颜色为黑或白.两人轮流操作.每次操作选择一个白格,假设它的下标为\(x\).接着,选择一个大小在\(1-n/x\)之间的整数\(k\),然后将下标为\(x\).\(2x\).....\(kx\)的格子都进行颜色翻转.不能操作的人输.问先手是否有必胜策略. \(30pts\ n\leq20\) \(50pts\ n\leq10^6\) \(100pts\ n\leq10^9,w