首页 > 其他 > 详细

[BZOJ 4589] Hard Nim

时间:2019-01-30 19:27:28      阅读:165      评论:0      收藏:0      [点我收藏+]

Description

Claris 和 NanoApe 在玩石子游戏,他们有 \(n\) 堆石子,规则如下:

  1. Claris 和 NanoApe 两个人轮流拿石子,Claris 先拿。
  2. 每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后 \(1\) 颗石子的人获胜。

不同的初始局面,决定了最终的获胜者,有些局面下先拿的 Claris 会赢,其余的局面 Claris 会负。

Claris 很好奇,如果这 \(n\) 堆石子满足每堆石子的初始数量是不超过 \(m\) 的质数,而且他们都会按照最优策略玩游戏,那么 NanoApe 能获胜的局面有多少种。

由于答案可能很大,你只需要给出答案对 \(10^9+7\) 取模的值。

Input

输入包含多组数据,每组数据一行两个正整数 \(n\)\(m\)

Output

每行一个整数表示答案。

Sample Input

3 7
4 13

Sample Output

6
120

HINT

\(1\le n\le 10^9, 2\le m\le 50000\)

不超过 \(80\) 组数据。

Solution

NIM 游戏先手必胜的条件是每堆石子数的异或和为 0。

相当于将一个只有质数次项的系数是 \(1\),其他项的系数是 \(0\)\(m\) 次多项式 \(fwt\) 异或卷积 \(n\) 次,最后输出常数项。

Code

#include <cstdio>

const int mod = 1000000007, inv = 500000004;
int n, m, nn, p[5135], np[50001], tot, a[65540], b[65540];

void euler(int n) {
    for (int i = 2; i <= n; ++i) {
        if (!np[i]) p[++tot] = i;
        for (int j = 1; j <= tot && i * p[j] <= n; ++j) {
            np[i * p[j]] = 1;
            if (i % p[j] == 0) break;
        }
    }
}
void fwt(int *a, int f) {
    for (int i = 1; i < n; i <<= 1)
        for (int j = 0, r = i << 1; j < n; j += r)
            for (int k = 0; k < i; ++k) {
                int x = a[j + k], y = a[i + j + k];
                a[j + k] = 1LL * (x + y) % mod, a[i + j + k] = 1LL * (x + mod - y) % mod;
                if (f == -1) a[j + k] = 1LL * a[j + k] * inv % mod, a[i + j + k] = 1LL * a[i + j + k] * inv % mod;
            }
}
int fastpow(int k) {
    for (; k; k >>= 1) {
        if (k & 1) for (int i = 0; i < n; ++i) b[i] = 1LL * b[i] * a[i] % mod;
        for (int i = 0; i < n; ++i) a[i] = 1LL * a[i] * a[i] % mod;
    }
    fwt(b, -1); return b[0];
}
int main() {
    euler(50000);
    while (~scanf("%d%d", &nn, &m)) {
        for (n = 1; n <= m; n <<= 1) {}
        for (int i = 0; i < n; ++i) a[i] = 0;
        for (int i = 1; i <= tot && p[i] <= m; ++i) a[p[i]] = 1;
        fwt(a, 1);
        for (int i = 0; i < n; ++i) b[i] = a[i];
        printf("%d\n", fastpow(nn - 1));
    }
    return 0;
}

[BZOJ 4589] Hard Nim

原文:https://www.cnblogs.com/fly-in-milkyway/p/10329231.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!