zoukankan      html  css  js  c++  java
  • 【BZOJ】3576: [Hnoi2014]江南乐

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3576


    很显然,这是一个multi-nim游戏。

    注意:1.一个点的SG值就是一个不等于它的后继点的SG的且大于等于零的最小整数。(mex)

       2.主游戏的SG值等于所有子游戏的异或和

      

       所以区分好主游戏和后继点的区别。

         一开始多个石子堆组合起来形成了一个主游戏。

       一个石子堆可以分为多个石子堆,每一种分发构成了一个主游戏,这些主游戏的异或和构成的当前这个点(状态)的SG函数。

        显然有一个${m^{2}}$做法,即记忆化搜索SG函数。  

            考虑${x/i}$只有$sqrt{n}$种取值,再考虑一下它们的奇偶性,然后分块来做。

    70Code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 100100
    10 #define llg long long 
    11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    12 llg n,m,bj[maxn],sg[maxn],T,F,a[maxn];
    13 
    14 llg dp(llg x)
    15 {
    16     if (bj[x]) return sg[x];
    17     bj[x]=1;
    18     sg[x]=0;
    19     bool e[maxn];
    20     memset(e,0,sizeof(e));
    21     for (llg m=2;m<=x;m++)
    22     {
    23         llg v1=m-x%m,v2=x%m;
    24         llg nsg=0;
    25         if (v1&1) nsg^=dp(x/m);
    26         if (v2&1) nsg^=dp(x/m+1);
    27         e[nsg]=1;
    28     }
    29     for (llg i=0;1;i++) if (!e[i]) {sg[x]=i; return sg[x];}
    30 }
    31 
    32 int main()
    33 {
    34     yyj("game");
    35     cin>>T>>F;
    36     for (llg i=0;i<F;i++) bj[i]=1;
    37     while (T--)
    38     {
    39         scanf("%lld",&n);
    40         llg ans=0;
    41         for (llg i=1;i<=n;i++)
    42         {
    43             scanf("%lld",&a[i]);
    44             ans^=dp(a[i]);
    45         }
    46         if (ans) printf("1");else printf("0");
    47         if (T) printf(" ");
    48     }
    49     return 0;
    50 }

    100Code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<vector>
     5 #include<cstdlib>
     6 #include<cmath>
     7 #include<cstring>
     8 using namespace std;
     9 #define maxn 100100
    10 #define llg int
    11 #define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    12 llg n,m,bj[maxn],sg[maxn],T,F,a[maxn];
    13 
    14 llg dp(llg x)
    15 {
    16     if (bj[x]) return sg[x];
    17     bj[x]=1;
    18     sg[x]=0;
    19     bool e[maxn];
    20     memset(e,0,sizeof(e));
    21     for (llg m=2,j=0;m<=x;m=j+1)
    22     {
    23         j=x/(x/m);
    24         llg v1=m-x%m,v2=x%m,cnt=j-m+1;
    25         llg nsg=0;
    26         if (v1&1) nsg^=dp(x/m);
    27         if (v2&1) nsg^=dp(x/m+1);
    28         e[nsg]=1;
    29         if (cnt>=2)
    30         {
    31             nsg=0;
    32             if (((m+1)-x%(m+1))&1) nsg^=dp(x/(m+1));
    33                    if ((x%(m+1))&1) nsg^=dp(x/(m+1)+1);
    34                    e[nsg]=1;
    35         }
    36     }
    37     for (llg i=0;1;i++) if (!e[i]) {sg[x]=i; return sg[x];}
    38 }
    39 
    40 int main()
    41 {
    42     yyj("game");
    43     cin>>T>>F;
    44     for (llg i=0;i<F;i++) bj[i]=1;
    45     while (T--)
    46     {
    47         scanf("%d",&n);
    48         llg ans=0;
    49         for (llg i=1;i<=n;i++)
    50         {
    51             scanf("%d",&a[i]);
    52             ans^=dp(a[i]);
    53         }
    54         if (ans) printf("1");else printf("0");
    55         if (T) printf(" ");
    56     }
    57     return 0;
    58 }
    本文作者:xrdog 作者博客:http://www.cnblogs.com/Dragon-Light/ 转载请注明出处,侵权必究,保留最终解释权!
  • 相关阅读:
    解决IE8不兼容通过class名获取元素的方法
    移动端页面遇到过的各种坑
    强大的正则表达式
    弹性盒子布局
    vue环境搭建
    fullpage.js使用指南
    ES5原生api(1)
    双色球中奖率分析(python)
    使用python脚本的3D引擎Panda3d
    Python lambda介绍
  • 原文地址:https://www.cnblogs.com/Dragon-Light/p/6411602.html
Copyright © 2011-2022 走看看