一些数论知识点
Lucas定理:
$C_{b}^{a}\pmod p= C_{b/p}^{a/p}*C_{b \pmod p}^{a \pmod p}\pmod p$
通常在p较小时用。
对于$C_{b/p}^{a/p}$,递归计算,
对于$C_{b \pmod p}^{a \pmod p}$,通过预处理阶乘和阶乘的逆元求。
至于证明。。我也不会。
模板:洛谷3807
#include<cstdio> const int maxn=100000; typedef long long ll; ll fac[maxn+10],invfac[maxn+10]; ll fpow(ll a,ll b,ll p){ ll ans=1; for(;b;b>>=1,a=a*a%p) if(b&1) ans=ans*a%p; return ans; } ll prework(ll p){ fac[0]=invfac[0]=1; for(int i=1;i<=maxn;++i){ fac[i]=fac[i-1]*i%p; invfac[i]=fpow(fac[i],p-2,p); } } ll c(ll a,ll b,ll p){ if(a>b) return 0; return fac[b]*invfac[a]%p*invfac[b-a]%p; } ll lucas(ll a,ll b,ll p){ ll ans=1; for(;a;a/=p,b/=p) ans=ans*c(a%p,b%p,p)%p; return ans; } ll t,a,b,p; int main(){ scanf("%lld",&t); for(;t--;){ scanf("%lld%lld%lld",&a,&b,&p); prework(p); printf("%lld\n",lucas(b,a+b,p)); } return 0; }
中国剩余定理:
模板:XJOI2190
#include<cstdio> typedef long long ll; const int mod[4]={0,23,28,33}; int a[6],cas,ans,p=mod[1]*mod[2]*mod[3],phi[4],d; int phi_c(int x){ int ans=x; for(int i=2;i*i<=x;++i) if(x%i==0){ ans=ans/i*(i-1); for(;x%i==0;x/=i); } if(x>1) ans=ans/x*(x-1); return ans; } int fpow(int a,int b){ int ans=1; for(;b;b>>=1,a=a*a%p) if(b&1) ans=ans*a%p; return ans; } int main(){ for(int i=1;i<=3;++i) phi[i]=phi_c(mod[i]); for(scanf("%d%d%d%d",&a[1],&a[2],&a[3],&d);a[1]!=-1||a[2]!=-1||a[3]!=-1||d!=-1;scanf("%d%d%d%d",&a[1],&a[2],&a[3],&d)){ ans=0; for(int i=1;i<=3;++i){ int now=1; for(int j=1;j<=3;++j) if(i!=j) now*=mod[j]; (ans+=a[i]*now%p*fpow(now,phi[i]-1)%p)%=p; } for(;ans<=d;ans+=p); ans-=d; printf("Case %d: the next triple peak occurs in %d days.\n",++cas,ans); } }