S
o
u
c
e
:
Souce:
Souce:ACM-ICPC 2018 南京赛区网络预赛
P
r
o
b
l
e
m
:
Problem:
Problem:
n
=
1
e
10000000
堆
石
头
;
f
(
i
)
=
(
a
f
(
i
−
1
)
4
+
b
f
(
i
−
1
)
3
+
c
f
(
i
−
1
)
2
+
d
f
(
i
−
1
)
1
+
e
−
1
)
%
k
+
1
,
(
k
≤
2
12
)
,
表
示
每
堆
石
头
的
大
小
。
求
多
少
个
石
头
子
集
可
以
使
得
n
i
m
游
戏
的
先
手
必
胜
。
n=1e10000000堆石头;f(i)=(af(i-1)^4+bf(i-1)^3+cf(i-1)^2+df(i-1)^1+e - 1)\%k+1, (k \le 2^{12}),表示每堆石头的大小。求多少个石头子集可以使得nim游戏的先手必胜。
n=1e10000000堆石头;f(i)=(af(i−1)4+bf(i−1)3+cf(i−1)2+df(i−1)1+e−1)%k+1,(k≤212),表示每堆石头的大小。求多少个石头子集可以使得nim游戏的先手必胜。
I
d
e
a
:
Idea:
Idea:
线
性
基
。
A
n
s
=
2
n
−
2
n
−
r
a
n
k
线性基。Ans = 2^n-2^{n-rank}
线性基。Ans=2n−2n−rank。
C
o
d
e
:
Code:
Code:
#include<bits/stdc++.h>
using namespace std;
#define Toocold
#define I inline
#define lc o<<1
#define rc o<<1|1
#define fi first
#define se second
#define pb push_back
#define ALL(X) (X).begin(), (X).end()
#define bcnt(X) __builtin_popcountll(X)
#define CLR(A, X) memset(A, X, sizeof(A))
using DB = double;
using LL = long long;
using PII = pair<int, int>;
#ifdef Toocold
#define dbg(args...)\
do { cout << "DEBUG: " << #args << " -> "; err(args); } while(0)
#else
#define dbg(...)
#endif // Toocold
void err() { puts(""); }
template<template<typename...> class T, typename t, typename... Args>
void err(T<t> a, Args... args) { for(auto x:a) cout << x << ' '; err(args...); }
template<typename T, typename... Args>
void err(T a, Args... args) { cout << a << ' '; err(args...); }
/*-----------------------------------------------------------------------------*/
const int N = (1<<12)+10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
//const DB eps = 1e-8;
LL qpow(LL a, LL b) {
b = (b+MOD-1)%(MOD-1);
LL ret = 1;
while(b) {
if(b&1) ret = ret*a%MOD;
a = a*a%MOD;
b >>= 1;
}
return ret;
}
struct LinearBasis {
int Rank;
LL a[65];
void init() { CLR(a, 0); Rank = 0; }
void Insert(LL t) {
for(int j = 60; j >= 0; j--) if(t>>j&1) {
if(a[j]) { t ^= a[j]; continue; }
for(int k = 0; k < j; k++) if(t>>k&1) t ^= a[k];
for(int k = j+1; k <= 60; k++) if(a[k]>>j&1) a[k] ^= t;
a[j] = t; Rank++;
return;
}
}
}A;
const int M = 1e7+10;
char s[M];
bool vis[N];
I void work() {
scanf("%s", s);
int len = strlen(s), n = 0;
int flag = 0;
for(int i = 0; i < len; i++) {
n = (n*10LL+s[i]-'0')%(MOD-1);
if(n > N) flag = INF;
}
LL x, a, b, c, d, e, ans = qpow(2, n);
scanf("%lld %lld%lld%lld%lld%lld", &x, &a, &b, &c, &d, &e);
int k; scanf("%d", &k);
if(n > k) flag = INF;
if(flag == 0) flag = n;
A.init();
while(!vis[x] && flag) {
vis[x] = 1; flag--;
A.Insert(x);
x = (a*x*x*x*x+b*x*x*x+c*x*x+d*x+e-1)%k+1;
}
(ans -= qpow(2, (n-A.Rank)%(MOD-1))) %= MOD;
printf("%lld\n", (ans+MOD)%MOD);
}
int main() {
work();
return 0;
}