昨天我在和同学讨论这个题的时候,发现了一个奇妙的事情。
题解区的写法(包括我那位同学)
f(n,p,P)的写法都大同小异:
LL F(LL n,LL P,LL PK)
{
if(n==0) return 1;
LL rep=1,rem=1;
for(LL i=1;i<=PK;i++)
if(i%P)
rep=rep*i%PK;
for(LL i=n/PK * PK;i<=n;i++)
if(i%P)
rem=rem*(i%PK)%PK;
return F(n/P,P,PK)*qmi(rep,n/PK,PK)%PK*rem%PK;
}
但是我写的是:
ll frac(int u,int P)
{
ll ans= 1;
for(int i=2;i<=u;i++)
ans = ans * i % P;
return ans;
}
int f(ll u,ll p,ll P)
{
if(!u) return 1;
return f(u/p,p,P) *qmi(frac(p-1,P),(u/p),P) % P * frac(u%p,P) % P;
}
同学表示这样不对,我自己代入几组数据又觉得是对的,于是交了一发,AC了。。。
简单来说,正常写法以pk为余数循环节,我却以p为余数循环节,代码的其余部分等价。
如果这个写法正确,是不是会提高程序效率?
求大佬给出hack或证明正确性。