题目链接:传送门
思路: 题目其实就是求 G ∑ d ∣ n C ( n , d ) % 999911659 G^{\sum_{d|n}C(n,d)} \%999911659 G∑d∣nC(n,d)%999911659的值,因为999911659是素数,我们我们可以用欧拉定理缩小幂次让原方程变为 G ∑ d ∣ n C ( n , d ) % ( 999911658 ) % 999911659 G^{\sum_{d|n}C(n,d)\%(999911658)} \%999911659 G∑d∣nC(n,d)%(999911658)%999911659,但是n太大,求幂次中的 ∑ d ∣ n C ( n , d ) % 999911658 \sum_{d|n}C(n,d)\%999911658 ∑d∣nC(n,d)%999911658的值就不太现实,所以我们可以考虑将999911658分解素因子 2 , 3 , 4679 , 35617 2, 3,4679,35617 2,3,4679,35617的乘积,然后分别求 ∑ d ∣ n C ( n , d ) % 2 \sum_{d|n}C(n,d)\%2 ∑d∣nC(n,d)%2, ∑ d ∣ n C ( n , d ) % 3 \sum_{d|n}C(n,d)\%3 ∑d∣nC(n,d)%3, ∑ d ∣ n C ( n , d ) % 4679 \sum_{d|n}C(n,d)\%4679 ∑d∣nC(n,d)%4679, ∑ d ∣ n C ( n , d ) % 35617 \sum_{d|n}C(n,d)\%35617 ∑d∣nC(n,d)%35617。然后用CRT合并即可。
现在问题转化为大组合数取余小质数,此时我们可以使用 l u c a s lucas lucas定理:
C ( a , b ) % p = C ( a % p , b % p ) ∗ C ( a / p , b / p ) % p C(a,b)\%p=C(a\%p,b\%p)*C(a/p,b/p)\%p C(a,b)%p=C(a%p,b%p)∗C(a/p,b/p)%p
就可以求出来了。
不过需要额外特判 G G G是 999911659 999911659 999911659的倍数的情况。
代码:
#include
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1e5+100;
const int inf=0x3f3f3f3f;
ll fac[N],tf;//因子
void dps_fac(ll n)//分解n的所有因子
{
tf=0;
for(int i=1;i*i<=n;++i){
if(n%i==0){
fac[tf++]=i;
if(n/i!=i) fac[tf++]=n/i;
}
}
}
ll pf[20],tp;//素因子
void dps_p(ll n)//分解n的素因子
{
tp=0;
for(ll i=2;i*i<=n;++i){
while(n%i==0){
pf[tp++]=i;
n/=i;
}
}
if(n!=1) pf[tp++]=n;
}
ll qpow(ll a,ll b,ll p)
{
if( a <= 0) return 0;
ll ans=1;
while(b)
{
if(b&1) ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
ll f[40005];//n!%mod
void init(ll mod)
{
f[0]=1;
for(int i=1;i<=36000;++i) f[i]=(f[i-1]*i)%mod;
}
ll C(ll n,ll m,ll p)//要求:预处理mod p的阶乘f[]
{
if(n>n>>g;
if(g%mod==0){
cout<<0<