zoukankan      html  css  js  c++  java
  • bzoj4589 FWT xor版本

    4589: Hard Nim

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 865  Solved: 484
    [Submit][Status][Discuss]

    Description

     
    Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下:
    1. Claris和NanoApe两个人轮流拿石子,Claris先拿。
    2. 每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。
    不同的初始局面,决定了最终的获胜者,有些局面下先拿的Claris会赢,其余的局面Claris会负。
    Claris很好奇,如果这n堆石子满足每堆石子的初始数量是不超过m的质数,而且他们都会按照最优策略玩游戏,那么NanoApe能获胜的局面有多少种。
    由于答案可能很大,你只需要给出答案对10^9+7取模的值。

    Input

    输入文件包含多组数据,以EOF为结尾。
    对于每组数据:
    共一行两个正整数n和m。
    每组数据有1<=n<=10^9, 2<=m<=50000。
    不超过80组数据。
     

    Output

     

    Sample Input

    3 7
    4 13

    Sample Output

    6
    120

    HINT

    Source

    Topcoder SRM 518 Div1 Hard Nim By Tangjz

    这题是一个NIM游戏,根据结论,先手输的情况只有所有的石子数xor起来的数为0

    https://blog.csdn.net/jr_mz/article/details/51606673

    这个blog比我自己瞎比比好多了。

     1 #include<cstring>
     2 #include<cmath>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstdio>
     6 
     7 #define N 50007
     8 #define ll long long
     9 #define P 1000000007
    10 #define inv 500000004
    11 using namespace std;
    12 inline int read()
    13 {
    14     int x=0,f=1;char ch=getchar();
    15     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    16     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    17     return x*f;
    18 }
    19 
    20 int n,m,len,num;
    21 ll A[(1<<18)+5],B[(1<<18)+5];
    22 int pri[N],np[N];
    23 
    24 void FWT(ll *a,int flag)
    25 {
    26     ll x,y;
    27     for (int h=1;h<len;h<<=1)
    28         for(int j=0;j<len;j+=(h<<1))
    29             for(int k=j;k<j+h;k++)
    30             {
    31                 if (flag==1) x=a[k],y=a[k+h],a[k]=(x+y)%P,a[k+h]=(x-y+P)%P;
    32                 else x=a[k],y=a[k+h],a[k]=(x+y)*inv%P,a[k+h]=((x-y)*inv%P+P)%P;
    33             }
    34 }
    35 void pow(ll *a,ll y)
    36 {
    37     ll *b=B;b[0]=1;
    38     FWT(a,1),FWT(b,1);
    39     while(y)
    40     {
    41         if(y&1) for(int i=0;i<len;i++) b[i]=a[i]*b[i]%P;
    42         for(int i=0;i<len;i++)
    43             a[i]=a[i]*a[i]%P;
    44         y>>=1;
    45     }
    46     FWT(b,-1);
    47 }
    48 int main()
    49 {
    50     for(int i=2;i<=50000;i++)
    51     {
    52         if(!np[i])  pri[++num]=i;
    53         for(int j=1;j<=num&&i*pri[j]<=50000;j++)
    54         {
    55             np[i*pri[j]]=1;
    56             if(i%pri[j]==0) break;
    57         }
    58     }
    59     while(~scanf("%d%d",&n,&m))
    60     {
    61         for(len=1;len<=m;len<<=1);
    62         memset(A,0,sizeof(A));
    63         memset(B,0,sizeof(B));
    64         for(int i=1;i<=num&&pri[i]<=m;i++)
    65             A[pri[i]]=1;
    66         pow(A,n);
    67         printf("%lld
    ",B[0]);
    68     }
    69 }
  • 相关阅读:
    wp8 入门到精通 测量代码执行时间
    过滤器——Filter
    hisui培训笔记
    监听器——servlet
    easyui导出excel表格和遇到的问题
    Java自定义注解
    Json
    Ajax
    探索Java中new一个对象时发生了什么
    SpringBoot常用注解
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8645876.html
Copyright © 2011-2022 走看看