P5221 Product 题解
来一个简单的 O(n) 解法:不用卡常,不用筛 \mu,\phi ,不用整除分块。
只需要线性筛质数。
直接列式:
莫比乌斯反演一下。
为了方便我们对答案
注意到
由于用写出
(原谅不会打大括号的 LaTeX)
若
否则
换句话说,我们只需要枚举所有能表示成
线性筛的时候,只需要保存一个质数表,一个表示每个数是否为质数的
最终以
code:
#include <bits/stdc++.h>
const int mod = 104857601;
inline int mul(int x, int y){
return (int)(1ll * x * y % (1ll * mod));
}
inline int add(int x, int y){
return x + y >= mod ? x + y - mod : x + y;
}
inline int minus(int x, int y){
return x < y ? x - y + mod : x - y;
}
inline int Qpow(int x, int y){
int r = 1;
while(y){
if(y & 1) r = mul(r, x);
x = mul(x, x);
y >>= 1;
}
return r;
}
int n, ans = 1;
int p[100005], cnt = 0;
std::bitset <1000005> is;
void solve(){
scanf("%d", &n);
is.set();
is[1] = 0;
for(int i = 1; i <= n; ++i) ans = mul(ans, i);
ans = Qpow(ans, n);
for(int i = 2; i <= n; ++i){
if(is[i] == 1){
p[++cnt] = i;
int q = i, t = Qpow(i, mod - 2);
int s = 0;
while(q <= n){
s += 1ll * (n / q) * (n / q) % (mod - 1);
s >= mod - 1 ? s -= (mod - 1) : true;
if(i <= 1000) q *= i;
else break;
}
ans = mul(ans, Qpow(t, s));
}
for(int j = 1; j <= cnt && i * p[j] <= n; ++j){
is[i * p[j]] = 0;
if(i % p[j] == 0) break;
}
}
printf("%d\n", mul(ans, ans));
return ;
}
int main(){
int T = 1;
while(T--) solve();
return 0;
}
后记:作者非常菜,完全不会做这道简单题,一直到