这个题是接触积性函数的第一题,完全不会做
感觉题目强的变态...
对积性函数不了解的同学可以百度下,主要参考的是它的性质以及哪几个常见的函数是积性函数
常见的有:
欧拉函数 - f(n) = n*(1-1/p1)*(1-1/p2)* ... *(1-1/pk)//pi为素数
d(n) -n的正因子数目
σ(n) -n的所有正因子之和
下面是摘自别人的题解,感觉还是读得不太懂
----------------------------------------------------------------------------------------------------------
1.证明p是素数时He[p] = 2.
x^2=x(mod p) —> p | x*(x-1).
因为x<p, 所以p不整除x也不整除x-1.
所以成立的情况下是x=1或者x=0.
He[p^k]=2,证明:
x^2 = x(mod p^k) -----> p^k | x*(x-1)
因为x<p^k, 所以当x不是p的倍数时,必然有gcd(p^k, x*(x-1)) == 1
而当x是p的倍数是,两侧同时除以gcd(p^k, x),又得到上面的形式(对x-1同理)
所以He[p^k] = 2
2.证明对于不同的两个素数p和q,He[p*q]=4=He[p]*He[q];
首先x=0和x=1是肯定成立的,
现在由x^2=x(mod p*q) —> p*q | x(x-1)
假设x=k*p[k<q]
——>p*q | k*p(k*p-1)
——>q | k*(k*p-1)
——>q | (k*p-1) 因为k<q q是素数 所以gcd(k,q)=1
——>k*p+t*q=1
这里就变成了这个方程的解,由扩展欧几里得知,这个方程有解
但是k在[0,q-1]之内的解就一个,所以这里多一个解,同理设x=k*p又有一个解
所以x^2=x(mod p*q)有4个解(x=0 ,x=1 ,x=k*p, x=k*q)
—>He[p*q]=4=He[p]*He[q];
那么He[p1^r1*p2^r2*……*pk^rk]=2^k然后可以证明HeHe只需要算n以内每个素数的倍数的个数.
举个例子:
计算HeHe[6] = He[1]*He[2]*He[3]*He[4]*He[5]*He[6]
He[1] = 2^0
He[2] = 2^1
He[3] = 2^1
He[4] = 2^1 = He[2*2] = He[2]
He[5] = 2^1
He[6] = 2^2 = He[2*3] = He[2] * He[3]
故He[6] = He[2]^3*He[3]^2*He[5]
题目代码如下:
#include <cstdio>
#include <iostream>
#define N 10000005
#define LL long long
using namespace std;
int prime[N], cnt;
bool vis[N];
void gen_primes() {
int i, j;
cnt = 0;
for(i=2; i<=N; ++i) {
if(!vis[i]) {
prime[cnt++] = i;
for(j=i+i; j<N; j+=i)
vis[j] = 1;
}
}
}
LL Pow(LL a, LL b, LL c) {
LL ans = 1;
while(b) {
if(b & 1)
ans = ans*a%c;
a = a*a%c;
b >>= 1;
}
return ans;
}
int main(void) {
int T, n, m, i, j;
LL ans;
gen_primes();
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
ans = 0;
for(i=0; i<cnt; ++i) {
if(prime[i] > n)
break;
ans += n/prime[i];
}
cout << Pow(2, ans, m) << endl;
}
return 0;
}