[BZOJ4589]-Hard Nim-FWT

13人阅读 评论(0) 收藏 举报
分类:

说在前面

并没有什么想说的,但是要保持格式=w=


题目

BZOJ4589传送门

题面

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

输入输出格式

输入格式:
多组数据,EOF结束
每行两个整数N和M,含义如题

输出格式:
对于每组数据,输出答案


解法

emmmmm……
这道题还算比较简单吧,先写出dp式子:dp[i][j]表示,前i堆石子,异或和为j的方案数。
转移就是dp[i][j]=kp[r]=jdp[i1][k],其中p[r]是一个不大于M的质数,最后答案就是dp[N][0]

然后发现这就是一个异或卷积,于是构造数组b[],令b[i]=1 (i is prime),其余为0。对b[]求一个正变换,然后快速幂一下,再逆变换回去就好了


下面是自带大常数的代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

const int P = 1e9 + 7 , inv2 = 500000004 ;
bool isnotp[50005] ;
int N , M , p[50005] , pcnt , a[100100] , tt ;

void preWork(){
    for( int i = 2 ; i <= 50000 ; i ++ ){
        if( !isnotp[i] ) p[++pcnt] = i ;
        for( int j = 1 ; j <= pcnt && i * p[j] <= 50000 ; j ++ ){
            isnotp[ i*p[j] ] = true ;
            if( i % p[j] == 0 ) break ;
        }
    } isnotp[1] = true ;
}

long long s_pow( long long x , int b ){
    long long rt = 1 ;
    while( b ){
        if( b&1 ) rt = rt * x %P ;
        x = x * x %P , b >>= 1 ;
    } return rt ;
}

void FWT( int *a , int lf , int rg , bool rev ){
    if( lf == rg ) return ;
    int siz = ( rg - lf + 1 ) >> 1 , t0 , t1 ;
    FWT( a , lf , lf + siz - 1 , rev ) ;
    FWT( a , rg - siz + 1 , rg , rev ) ;
    for( int i = lf + siz - 1 ; i >= lf ; i -- ){
        t0 = a[i] , t1 = a[i+siz] ;
        if( rev ){
            a[i] = 1LL * ( t0 + t1 ) * inv2 %P ;
            a[i+siz] = 1LL * ( t0 - t1 ) * inv2 %P ;
        } else a[i] = ( t0 + t1 )%P , a[i+siz] = ( t0 - t1 )%P ;
    }
}

void solve(){
    for( int i = 1 ; i <= M ; i ++ )
        if( !isnotp[i] ) a[i] = 1 ;
    for( tt = 1 ; tt <= M ; tt <<= 1 ) ;
    FWT( a , 0 , tt - 1 , 0 ) ;
    for( int i = 0 ; i < tt ; i ++ )
        a[i] = s_pow( a[i] , N ) ;
    FWT( a , 0 , tt - 1 , 1 ) ;
    printf( "%d\n" , ( a[0] + P )%P ) ;
}

int main(){
    preWork() ;
    while( scanf( "%d%d" , &N , &M ) != EOF ){
        memset( a , 0 , M << 3 ) ;
        solve() ;
    }
}
查看评论

bzoj4589 Hard Nim

http://www.lydsy.com/JudgeOnline/problem.php?id=4589 题意:石子堆数为N且每堆石子的数量都是不大于M的质数的Nim游戏,求先手必败的局面数量模10...
  • jr_mz
  • jr_mz
  • 2016-06-07 22:03:48
  • 1283

[FWT] BZOJ 4589 Hard Nim

FWT相关 Fast Walsh-Hadamard Transform (快速沃尔什变换)#include #include #include using namespace std; typede...
  • u014609452
  • u014609452
  • 2017-04-09 20:42:02
  • 502

bzoj 4589: Hard Nim 异或规则下的多项式乘法

定义(a$b)i = Σaj * bi^j ,那么题目相当于求A^N的第0项,其中Ai=[i为质数且i        显然我们可以用快速幂+分治乘做到N^1.59logN,光荣TLE。        ...
  • lych_cys
  • lych_cys
  • 2016-05-17 16:19:05
  • 1679

[bzoj4589]Hard Nim【FWT】

【题目链接】   http://www.lydsy.com/JudgeOnline/problem.php?id=4589 【题解】   就是求nnn堆石子异或和为000的方案数。   这个东...
  • D_Vanisher
  • D_Vanisher
  • 2018-03-07 13:09:39
  • 10

【BZOJ4589】Hard Nim

【题目链接】点击打开链接【思路要点】异或FWT模板题。时间复杂度\(O(TM(LogN+LogM))\)。【代码】#include&amp;lt;bits/stdc++.h&amp;gt; using...
  • qq_39972971
  • qq_39972971
  • 2018-03-07 12:33:52
  • 19

BZOJ4589: Hard Nim

筛出不超过m的质数,然后可以DP f[i][j]=∑f[i−1][a]∗f[i−1][b](a xor b=j)f[i][j]=\sum f[i-1][a]*f[i-1][b](a \ xor\ b...
  • L_0_Forever_LF
  • L_0_Forever_LF
  • 2017-04-05 21:16:14
  • 601

BZOJ4589 Hard Nim

造一个序列,凡是第m以内的素数项为1,否则为0,对这个序列求生成函数,相当于做n次异或卷积后求0次项的系数 异或卷积嘛,普通卷积是一个sigma i+j=k,异或卷积就是sigma i^j=k 求...
  • neither_nor
  • neither_nor
  • 2016-05-24 20:00:16
  • 1031

BZOJ 4589(Hard Nim-FWT测试)

题目:给n个不超过m的素数,求xor和=0的方案数,FWT变换裸题。 题目2关于F逆元的公式: inv(2)=(F+1)>>1inv(2)=(F+1)>>1 证:[(F+1)>>1]∗2(mod...
  • nike0good
  • nike0good
  • 2017-01-22 00:41:14
  • 351

[FWT+Nim游戏] BZOJ4589: Hard Nim

题意Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下: 1.Claris和NanoApe两个人轮流拿石子,Claris先拿。 2.每次只能从一堆中取若干个,可将一堆全取走,但不可...
  • CHHNZ
  • CHHNZ
  • 2017-07-20 21:52:14
  • 206

bzoj4589:Hard Nim(fwt+倍增)

某位高一dalao看了一道我不会的题,让我十分好奇,然后听说了一种fwt的算法。 (也许明天出成绩后就退役了…) 题面 经过简单的博弈论分析后的题意: 构造一个n个数的数组,每个都为小于m的质...
  • q582116859
  • q582116859
  • 2017-11-19 22:20:47
  • 99
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 2万+
    积分: 2117
    排名: 2万+
    博客专栏