(南京区域资格赛)K - The Great Nim Game(博弈)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/OscaronMar/article/details/82391938

Nim is a famous game as you know. Nim is a 222-player game featuring several piles of stones. Players alternate turns, and on his/her turn, a player’s move consists of removing one or more stones from any single pile. Play ends when all the stones have been removed. The first player who can’t remove is declared as the loser.

Now you want to play the Great Nim Game. In the other words, you want to choose several (0(0(0 ~ N)N)N) pile(s) from NNN piles of stones. You want know how many choices you have making sure that the first player must win. They both try their best (optimal strategy) to win through the game.
Input

The first line contains two numbers N x1N\ x_1N x1​, denoting the number of piles and the number of stones in the first pile.

The second line contains five integers a,b,c,d,ea, b, c, d, ea,b,c,d,e.

The third line contains one integer kkk, denoting a function

f(x)=f(x)=f(x)=
(ax4+bx3+cx2+dx1+e−1)%k+1(ax^4+bx^3+cx^2+dx^1+e - 1)\%k+1(ax4+bx3+cx2+dx1+e−1)%k+1.

With these, you can figure out the number of stones in the iii-th pile xi=f(xi−1)(1

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
#define ll long long
const int INF = 0x3f3f3f3f;
const int MAXN = 1e7 + 10;
const int MAXM = 2e6 + 10;
const ll mod = 1e9 + 7;

bool vis[4105];
int dp[2][8192];
vector<int>vec;
int f[4105];

ll pow_mod(ll a, ll n) {
    ll ans = 1;
    while(n) {
        if(n & 1) ans = ans * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return ans;
}

int main() {
    ll ans = 0;
    char ch;
    int len = 0;
    int n = 1e9;
    while(1) {
        scanf("%c", &ch);
        if(ch == ' ') break;
        ans = pow_mod(ans, 10);
        if(len == 0) ans = 1;
        ans = ans * (1ll << (ch - '0')) % mod;
        if(len <= 5) {
            if(len == 0)
                n = 0;
            n = n * 10 + ch - '0';
            len++;
        }
    }
    int x;
    scanf("%d", &x);
    int temp = x;
    int a, b, c, d, e, k;
    scanf("%d%d%d%d%d%d", &a, &b, &c, &d, &e, &k);
    vec.push_back(x);
    vis[x] = true;
    for(int i = 1; i <= 4100; i++) {
        int x1 = 1ll * a * i * i % k * i * i % k;
        int x2 = 1ll * b * i * i % k * i % k;
        int x3 = 1ll * c * i * i % k;
        int x4 = 1ll * d * i;
        x = (x1 + x2 + x3 + x4 + e - 1) % k + 1;
        f[i] = x;
    }
    int all = 0;
    while(all < n) {
        all++;
        int now = f[temp];
        if(!vis[now]) {
            vis[now] = true;
            vec.push_back(now);
            temp = now;
        } else break;
    }
    int sz = vec.size();
    dp[0][0] = 1;
    int pre = 1, now = 0;
    for(int i = 1; i <= sz; i++) {
        swap(pre, now);
        int num = vec[i - 1];
        for(int j = 0; j < 8192; j++) dp[now][j] = dp[pre][j];
        for(int j = 0; j < 8192; j++) {
            dp[now][j ^ num] += dp[pre][j];
            if(dp[now][j ^ num] >= mod) dp[now][j ^ num] -= mod;
        }
    }
    ll sum = 0;
    for(int i = 1; i < 8192; i++) {
        sum += dp[now][i];
        if(sum >= mod) sum -= mod;
    }
    ll inv = pow_mod(2, sz);
    inv = pow_mod(inv, mod - 2);
    ans = ans * inv % mod;
    ans = ans * sum % mod;
    printf("%lld\n", ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/OscaronMar/article/details/82391938
今日推荐