zoukankan      html  css  js  c++  java
  • [HAOI2015] 数组游戏

    有一个长度为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;
        }
    }
    
  • 相关阅读:
    python 中的[::-1]
    python 闭包
    elastic
    文件上传进度条修改
    python decorator的理解
    同方爬虫--面试题
    js typeof
    浅谈软件项目实施
    数独·唯一性技巧(Uniqueness)-1
    数独二
  • 原文地址:https://www.cnblogs.com/mollnn/p/12400733.html
Copyright © 2011-2022 走看看