1.n,m≤10^3,p No requirements
The relationship between Yang Hui Triangle and combinatorial number is used to solve the violence, O (n^2).
2.n,m≤10^6,p≤10^9 could be composite.
Decomposition factorization + fast power
3.n,m≤10^9,p≤10^5 and is prime
Lucas theorem, multiple queries can preprocess factorial and factorial of the inverse element. (See bzoj1951 code)
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath > #include <algorithm> #define F (I,j,n) for (int. i=j;i<=n;i++) #define D (i,j,n) for (int i=j;i>=n;i--) # Define ll long Long#define maxn 100005using namespace Std;const int P[5]={2,3,4679,35617,999911658};int N,M,FAC[MAXN], Inv[maxn];inline int read () {int X=0,f=1;char ch=getchar (); while (ch< ' 0 ' | | Ch> ' 9 ') {if (ch== '-') F=-1;ch=getchar ();} while (ch>= ' 0 ' &&ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar ();} return x*f;} Inline ll Power (ll x,ll Y,ll p) {ll ans=1;for (; y;y>>=1,x=x*x%p) if (y&1) Ans=ans*x%p;return ans;} inline void exgcd (ll a,ll b,ll &x,ll &y) {if (!b) {X=1;y=0;return;} EXGCD (b,a%b,x,y); int t=x;x=y;y=t-a/b*x;} inline ll Getinv (ll A,ll b) {ll x,y;exgcd (a,b,x,y); return (x%b+b)%b;} inline int C (int n,int M,int p) {if (n<m) return 0;if (n<p&&m<p) return Fac[n]*inv[m]%p*inv[n-m]%p;return C (n/p,m/p,p) *c (n%p,m%p,p)%p;} int main () {n=read (); M=reaD (); ll ans=0;m%= (p[4]+1); if (!m) {printf ("0\n"); return 0;} F (i,0,3) {fac[0]=1; F (j,1,p[i]-1) fac[j]=fac[j-1]*j%p[i];inv[0]=inv[1]=1; F (j,2,p[i]-1) inv[j]= (p[i]/j+1) *inv[j-p[i]%j]%p[i]; F (j,2,p[i]-1) inv[j]=inv[j-1]*inv[j]%p[i];ll T1=0,T2=GETINV (P[4]/p[i],p[i]); for (int j=1;j*j<=n;j++) if (n%j==0) { (T1+=c (N,j,p[i]))%=p[i];if (j*j==n) continue; (T1+=c (N,n/j,p[i]))%=p[i];} (ans+= (LL) p[4]/p[i]%p[4]*t2%p[4]*t1%p[4])%=p[4];} (Ans+=p[4])%=p[4];cout<<power (m,ans,p[4]+1) <<endl;}
4.n,m≤10^9,p≤10^5 could be composite.
We decompose p into a number of pi^ci, and then take the scheme number to the pi^ci of each one, and finally merge it with the Chinese remainder theorem.
The main problem now is how to find out n! MoD Pi^ci and n! on the inverse of Pi^ci, (where pi is prime).
Assuming pi=5 (the rest of the same), we can find the following relationship:
N!= (1*2*3*4*6*7*8*9*11* ...) *5^ (N/5) * (N/5)!
The items of multiples of all p are processed separately, and the latter (N/5) can be solved recursively.
So we can preprocess the factorial, omit the multiple of p, and replace it with 1. Similar to the numerator and denominator, the inverse of the preprocessing factorial. The power of the last p is used as a fast power. Note that the number of final p is the number of times the denominator is subtracted from the numerator.
Finally, attention should be paid to the handling of sum<n and sum>n cases. (See bzoj2142 code)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib > #include <algorithm> #define F (I,j,n) for (int. i=j;i<=n;i++) #define D (i,j,n) for (int i=j;i>=n;i--) # Define MAXN 200005#define ll long longusing namespace Std;ll n,m,mod,cnt,sum,tot;ll A[MAXN],B[MAXN],P[MAXN],PC[MAXN], Fac[maxn];inline ll Read () {ll x=0,f=1;char Ch=getchar (); while (ch< ' 0 ' | | Ch> ' 9 ') {if (ch== '-') F=-1;ch=getchar ();} while (ch>= ' 0 ' &&ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar ();} return x*f;} inline void divide (int n) {for (int i=2;i*i<=n;i++) if (n%i==0) {p[++cnt]=i;pc[cnt]=1;while (n%i==0) pc[cnt]*=i,n/=i;} if (n>1) p[++cnt]=n,pc[cnt]=n;} Inline ll Power (ll x,ll Y,ll p) {ll ans=1;for (; y;y>>=1,x=x*x%p) if (y&1) Ans=ans*x%p;return ans;} inline void exgcd (ll a,ll b,ll &x,ll &y) {if (!b) {X=1;y=0;return;} EXGCD (b,a%b,x,y); ll T=x;x=y;y=t-a/b*x;} Inline LL inv (ll A,ll b) {ll x,y;exgcd (a,b,x,y); return (x%b+b)%b;} Inline ll Calc (ll n,ll p,ll pc){if (n<p) return Fac[n];tot+=n/p;return fac[n%pc]*power (fac[pc-1],n/pc,pc)%pc*calc (N/P,P,PC)%pc;} inline ll solve (ll p,ll pc) {fac[0]=1; F (i,1,pc-1) fac[i]=fac[i-1]* (i%p?i:1)%pc;tot=0;ll T1=calc (n,p,pc), T2=1;ll Tmp=tot; F (i,1,pc-1) fac[i]=fac[i-1]* (I%P?INV (I,PC): 1)%pc;tot=0; F (i,1,m) T2=t2*calc (a[i],p,pc)%pc;return t1*t2%pc*power (p,tmp-tot,pc)%pc;} int main () {mod=read (); N=read (); M=read (); F (i,1,m) {a[i]=read (); sum+=a[i];} if (sum>n) {printf ("impossible\n"); return 0;} if (sum<n) a[++m]=n-sum;divide (mod); F (i,1,cnt) b[i]=mod/pc[i];ll ans=0; F (i,1,cnt) {ll t1=solve (P[i],pc[i]), T2=INV (B[i],pc[i]); ans= (Ans+t1*t2%mod*b[i]%mod)%mod;} printf ("%lld\n", ans); return 0;}
Modulus of combination number