zoukankan      html  css  js  c++  java
  • [CSAcademy]Exponential Game

    题目大意:
      有n堆石子,A和B两人轮流进行操作:
      取走任意一堆石子,若这堆石子的个数是x个,那么可以放入x-1堆数量为0~x-1的石子。
      不能操作者负。

    思路:
      将每一堆石子作为一个子游戏,将石子的数量作为游戏状态。
      sg(x)=mex{sg(y)|y为x的后继状态}
      然而后继状态有很多,暴力构造肯定会超时。
      考虑找规律。
      sg(0)=0 sg(1)=1 sg(2)=2 sg(3)=4 sg(4)=8 ...
      发现sg(x)=2^(x-1)。
      为什么?
      当x=0时,无法进行操作,显然为必败状态;
      当x=1时,sg(x)=mex{sg(0)};
      当x=2时,sg(x)=mex{sg(0),sg(1)};
      当x=3时,sg(x)=mex{sg(0),sg(1),sg(2),sg(1 1),sg(2 2),sg(1 2)},其中sg(1 2)=3;
      ……
      发现2^0,2^1,...,2^k-1的数能异或出小于2^k的所有数。
      然而x<=1e9,2^x-1似乎要高精度?
      事实上我们发现每个SG值只有1位是1,其余位都是0,
      那么我们可以用一个set记录出现过的位,异或的时候只需要把有的去掉,没的加进来就可以了,由于n<=1e5,显然存得下。

     1 #include<cstdio>
     2 #include<cctype>
     3 #include<ext/hash_set>
     4 inline int getint() {
     5     register char ch;
     6     while(!isdigit(ch=getchar()));
     7     register int x=ch^'0';
     8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
     9     return x;
    10 }
    11 __gnu_cxx::hash_set<int> sg;
    12 int main() {
    13     for(register int T=getint();T;T--) {
    14         sg.clear();
    15         for(register int n=getint();n;n--) {
    16             const int x=getint()-1;
    17             if(sg.count(x)) {
    18                 sg.erase(x);
    19             } else {
    20                 sg.insert(x);
    21             }
    22         }
    23         puts(sg.empty()?"B":"A");
    24     }
    25     return 0;
    26 }
  • 相关阅读:
    Nginx降权启动
    Tomcat降权启动
    【转载】XSS学习笔记
    仪仗队(容斥,欧拉,打表)
    2012蓝桥杯
    HPU周赛题目解析
    蓝桥杯真题集2011
    cf公式专场-续
    24点游戏&&速算24点(dfs)
    Parallelogram Counting(平行四边形个数,思维转化)
  • 原文地址:https://www.cnblogs.com/skylee03/p/7613776.html
Copyright © 2011-2022 走看看