zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    stm32 oled学习
    PWM输出配置步骤
    IIC通信笔记
    运算放大器原理
    stm32跑马灯实现及蜂鸣器实验
    一个字节多少位
    pyQT编写界面调用摄像头
    PAT Advanced 1151 LCA in a Binary Tree (30) [树的遍历,LCA算法]
    PAT Advanced 1143 Lowest Common Ancestor (30) [二叉查找树 LCA]
    PAT Advanced 1147 Heaps (30) [堆,树的遍历]
  • 原文地址:https://www.cnblogs.com/dummyummy/p/9570163.html
Copyright © 2011-2022 走看看