[ARC151C] 01 Game 题解

· · 题解

题目大意

n 个格子,第 ii+1 相邻。初始 m 个格子里有 01,Takahashi 和 Aoki 轮流在没数字的格子里填 01,要保证相邻格子的数字不同,求谁赢。

思路

发现整个游戏被若干已存在的棋子分割成为若干个子游戏,考虑分别计算子游戏的 SG 值并计算异或和。

一个子游戏有且仅有四种情况。分别设 f_1(n),f_2(n),f_3(n),f_4(n) 表示长度为 n 的两端都没有、只有一端有、两端相同和两端不同的子游戏,则(注意 f_3(0) 无意义,\oplus 表示异或运算):

\begin{cases} f_1(n) = \operatorname{mex}_{i=1}^n(f_2(i-1)\oplus f_2(n-i))\\ f_2(n) = \operatorname{mex}_{i=1}^n(f_2(i-1)\oplus f_3(n-i),f_2(i-1)\oplus f_4(n-i))\\ f_3(n) = \operatorname{mex}_{i=1}^n(f_3(i-1)\oplus f_3(n-i),f_4(i-1)\oplus f_4(n-i))\\ f_4(n) = \operatorname{mex}_{i=1}^n(f_3(i-1)\oplus f_4(n-i),f_4(i-1)\oplus f_3(n-i))\\ \end{cases}

打表:

得到:\begin{cases}f_1(n) = n\bmod 2\\f_2(n) = n\\f_3(n) = 1\\f_4(n) = 0\end{cases}。考虑用归纳法证明:显然 n = 0,1 时成立。假如 0\sim n-1 时均成立,那么:

得证。

#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll n,m,pos,col,lascol,sgs;
int main(){
    scanf("%lld%lld",&n,&m);
    if(m==0){if(n&1) printf("Takahashi"); else printf("Aoki"); return 0;} // 特判 m=0 的情况 
    for(int i=1;i<=m;i++){
        scanf("%lld%lld",&pos,&col);
        if(i==1) sgs=pos-1; else sgs^=(col==lascol);
        if(i==m) sgs^=n-pos; lascol=col; // 首尾两段的 SG 为长度,中间的为两端点是否相同 
    } if(sgs==0) printf("Aoki"); else printf("Takahashi");
    return 0;
}