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;
}