结论: f j ∣ f i f_j|f_i fj∣fi 等价于 j ∣ i j|i j∣i。
证明:(来自DTZ巨佬)
于是询问就变成了求一个数的因数个数和因数的平方和。
设 x = p 1 k 1 p 2 k 2 ⋯ p m k m x=p_1^{k_1}p_2^{k_2}\cdots p_m^{k_m} x=p1k1p2k2⋯pmkm。
那么 x x x 的因数个数为 ∏ i = 1 m ( k i + 1 ) \prod\limits_{i=1}^m(k_i+1) i=1∏m(ki+1),因数平方和为 ∏ i = 1 m ∑ j = 0 k i p i 2 j \prod\limits_{i=1}^m\sum\limits_{j=0}^{k_i}p_i^{2j} i=1∏mj=0∑kipi2j。
用线性筛求解,有一个小 trick 是记录一个数 x x x 除尽其最小质因子后的数 n o p ( x ) nop(x) nop(x),具体实现过程详见代码。
#include<bits/stdc++.h>
#define N 10000010
using namespace std;
namespace modular
{
const int mod=1000000007;
inline int add(const int x,const int y){return x+y>=mod?x+y-mod:x+y;}
inline int dec(const int x,const int y){return x-y<0?x-y+mod:x-y;}
inline int mul(const int x,const int y){return 1ll*x*y%mod;}
}using namespace modular;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+(ch^'0');
ch=getchar();
}
return x*f;
}
int q,a,b,c;
int cnt,prime[N];
int nop[N],s1[N],s2[N];
bool notprime[N];
void init()
{
s1[1]=1,s2[1]=1;
for(int i=2;i<=c;i++)
{
if(!notprime[i])
{
prime[++cnt]=i;
nop[i]=1;
s1[i]=2;
s2[i]=add(mul(i,i),1);
}
for(int j=1,x;j<=cnt&&(x=(i*prime[j]))<=c;j++)
{
notprime[x]=1;
if(!(i%prime[j]))
{
nop[x]=nop[i];
s1[x]=mul(s1[nop[i]],add(s1[i/nop[i]],1));
s2[x]=mul(s2[nop[i]],add(mul(s2[i/nop[i]],mul(prime[j],prime[j])),1));
break;
}
nop[x]=i;
s1[x]=mul(s1[i],s1[prime[j]]);
s2[x]=mul(s2[i],s2[prime[j]]);
}
}
}
int main()
{
q=read();
int x=read();
a=read(),b=read(),c=read();
init();
int ans1=0,ans2=0;
while(q--)
{
ans1=add(ans1,add(s1[x],(x&1)));
ans2=add(ans2,add(s2[x],(x&1)*4));
x=(1ll*x*a+b)%c+1;
}
printf("%d\n%d\n",ans1,ans2);
return 0;
}
/*
2
2 2 1 8
*/