题目链接:https://www.luogu.org/problem/CF1228C
问题可以转化为:求质数 $p$ 在 $1sim n$ 中的每个数中的次幂之和.
因为 $p$ 是一个质数,只能由 $1$ 乘以 $p$ 表示出来,所以可以将问题转化为求 $p$ 在 $n!$ 中出现的次幂.
我们可以像提取公因式一样地去提取这个 $p$.
那么,先考虑 $p$ 的贡献:$1sim n$ 中能被 $p$ 整除的乘积为 $p^{frac{n}{p}} imes (frac{n}{p}!)$
然后递归处理啊 $frac{n}{p}!$ 中 $p$ 出现的次数.
由于 $p>2$,而 $n<10^8$,所以提取次数不会超过 $65$,复杂度是很优秀的.
#include <bits/stdc++.h> #define mod 1000000007 #define ll unsigned long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; vector<ll>v; ll qpow(ll base,ll k) { ll tmp=1ll; for(;k;k>>=1,base=base*base%mod) if(k&1) tmp=tmp*base%mod; return tmp; } int main() { int i,j; ll x,n,p; // setIO("input"); scanf("%lld%lld",&x,&n); p=x; for(i=2;i*i<=p;++i) { if(p%i==0) { v.push_back(i); for(;p%i==0;) p/=i; } } if(p>1) v.push_back(p); ll ans=1ll; for(i=0;i<v.size();++i) { ll m=n; ll now=0; while(m>=v[i]) { now+=m/v[i]; m/=v[i]; } ans=ans*qpow(v[i], now)%mod; } printf("%lld ",(long long)ans); return 0; }