一个需要知道的结论是
g
c
d
(
f
i
b
n
,
f
i
b
m
)
=
f
i
b
g
c
d
(
n
,
m
)
gcd(fib_n,fib_m)=fib_{gcd(n,m)}
gcd(fibn,fibm)=fibgcd(n,m),比较容易证明 于是
f
i
b
m
∣
f
i
b
n
⇒
m
∣
n
fib_m|fib_n\Rightarrow m|n
fibm∣fibn⇒m∣n,所以题目就是求
σ
0
(
n
)
,
σ
2
(
n
)
\sigma_0(n),\sigma_2(n)
σ0(n),σ2(n) 的前缀和 线筛一波,要特判
2
2
2 的情况因为
f
i
b
2
=
1
fib_2=1
fib2=1,有些头凸
#include<bits/stdc++.h>#define cs const
using namespace std;
typedef long long ll;
int read(){
int cnt = 0, f = 1; char ch = 0;
while(!isdigit(ch)){ ch = getchar(); if(ch =='-') f = -1;}
while(isdigit(ch)) cnt = cnt*10 + (ch-'0'), ch = getchar();return cnt * f;}
cs int Mod = 1e9 + 7;
int add(int a, int b){return a + b >= Mod ? a + b - Mod : a + b;}
int mul(int a, int b){return 1ll * a * b % Mod;}
int dec(int a, int b){return a - b < 0 ? a - b + Mod : a - b;}
void Add(int &a, int b){ a = add(a, b);}
void Mul(int &a, int b){ a = mul(a, b);}
int sqr(int a){return mul(a, a);}
cs int N = 1e7 + 50;
int Q, x, A, B, C, Sa, Sb;
int sig[N], sig2[N], mnp[N], vl[N], vl2[N], pc;
bool isp[N]; int prim[N/5];
void prework(int n){
sig[1]= sig2[1]= 1;
for(int i = 2; i <= n; i++){
if(!isp[i]){
prim[++pc]= i,
vl[i]= sig[i]= 2;
vl2[i]= sig2[i]= add(sqr(i),1);
mnp[i]= 1;}
for(int j = 1; j <= pc; j++){
if(prim[j] * i > n)break;
int nx = prim[j] * i; isp[nx]= 1;
if(i % prim[j]== 0){
mnp[nx]= mnp[i];
vl[nx]= add(vl[i],1);
vl2[nx]= add(mul(sqr(prim[j]),vl2[i]),1);
sig[nx]= mul(sig[mnp[nx]],vl[nx]);
sig2[nx]= mul(sig2[mnp[nx]],vl2[nx]);break;}
mnp[nx]= i;
vl[nx]= 2;
vl2[nx]= add(sqr(prim[j]),1);
sig[nx]= mul(sig[i],sig[prim[j]]);
sig2[nx]= mul(sig2[i],sig2[prim[j]]);}}}
int main(){
Q = read();
x = read(), A = read(), B = read(), C = read();
prework(C+1);
while(Q--){
if(x & 1) Add(Sa, 1), Add(Sb, 4);
Add(Sa, sig[x]);
Add(Sb, sig2[x]);
x =((ll)x * A + B) % C + 1;} cout << Sa <<'\n'<< Sb;return 0;}