1. 程式人生 > 其它 >P4720 【模板】擴充套件盧卡斯

P4720 【模板】擴充套件盧卡斯

技術標籤:數學

This way

題意:

在這裡插入圖片描述

題解:

存個模板,借用了別人的程式碼,好長學不來

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll qpow(ll a,ll b,ll mod){ll ans=1;for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;return ans;}
ll qpow(ll a,ll b){ll ans=1;for(;b;b>>=1,a=a*a)if(b&1)ans=ans*a;return
ans;} ll ex_gcd(ll a,ll b,ll& x,ll& y){ if(!b){ x=1,y=0; return a; } else { ll v=ex_gcd(b,a%b,y,x); y=y-a/b*x; return v; } } bool modular(ll a[],ll m[],ll k) { ll d,t,c,x,y,i; for(i=2;i<=k;i++) { d=ex_gcd(m[1],m[i]
,x,y); c=a[i]-a[1]; if(c%d) return 0; t=m[i]/d; x=(c/d*x%t+t)%t; a[1]=m[1]*x+a[1]; m[1]=m[1]*m[i]/d; } return 1; } ll inv(ll a,ll b) { ll x,y; ex_gcd(a,b,x,y); return (x%b+b)%b; } ll C(ll n,ll m,ll mod) { if(m>n) return 0; ll ans=
1,i,a,b; for(i=1;i<=m;i++) { a=(n+1-i)%mod; b=inv(i%mod,mod); ans=ans*a%mod*b%mod; } return ans; } ll C1(ll n,ll m,ll mod) { if(m==0) return 1; return C(n%mod,m%mod,mod)*C1(n/mod,m/mod,mod)%mod; } ll cal(ll n,ll p,ll t) { if(!n) return 1; ll x=qpow(p,t),i,y=n/x,temp=1; for(i=1;i<=x;i++) if(i%p) temp=temp*i%x; ll ans=qpow(temp,y,x); for(i=y*x+1;i<=n;i++) if(i%p) ans=ans*i%x; return ans*cal(n/p,p,t)%x; } ll C2(ll n,ll m,ll p,ll t) { ll x=qpow(p,t); ll a,b,c,ap=0,bp=0,cp=0,temp; for(temp=n;temp;temp/=p) ap+=temp/p; for(temp=m;temp;temp/=p) bp+=temp/p; for(temp=n-m;temp;temp/=p) cp+=temp/p; ap=ap-bp-cp; ll ans=qpow(p,ap,x); a=cal(n,p,t); b=cal(m,p,t); c=cal(n-m,p,t); ans=ans*a%x*inv(b,x)%x*inv(c,x)%x; return ans; } //計算C(n,m)%mod ll ex_lucas(ll n,ll m,ll mod) { ll i,t,cnt=0; ll A[205],M[205]; for(i=2;i*i<=mod;i++) if(mod%i==0) { t=0; while(mod%i==0) { t++; mod/=i; } M[++cnt]=qpow(i,t); if(t==1) A[cnt]=C1(n,m,i); else A[cnt]=C2(n,m,i,t); } if(mod>1) { M[++cnt]=mod; A[cnt]=C1(n,m,mod); } modular(A,M,cnt); return A[1]; } int main(){ ll n,m,mod; scanf("%lld%lld%lld",&n,&m,&mod); printf("%lld\n",ex_lucas(n,m,mod)); }