Description
给定P,求(Pi_{i=1}^m C_{n-w_1-w_2-...-w_{i-1}}^{w_i};mod;P)。(mleq 5)。
Solution
扩展Lucas的板子。
P不是质数的话可以先质因数分解,然后求出同余每个质数次幂的解,再CRT合并就吼了
(n!)怎么求还是注意一下吧,要先把和(p_i)不互质的部分拎出来算。拎出来的代码大概就是这样
for(int i=n;i;i/=c[cur])
now+=i/c[cur];
别的就没啥了。突然发现自己数论忘了好多,都是看的自己之前写的博客。
Code
#include<cmath>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using std::min;
using std::max;
using std::swap;
#define int long long
int p[100005],c[100005];
int P,w[10],tot,a[100005];
int exgcd(int a,int b,int &x,int &y){
if(!b){
x=1,y=0;
return a;
} int d=exgcd(b,a%b,y,x);
y-=a/b*x;return d;
}
int inv(int a,int b){
int x,y;
exgcd(a,b,x,y);
return (x%b+b)%b;
}
int getint(){
int X=0,w=0;char ch=0;
while(!isdigit(ch))w|=ch=='-',ch=getchar();
while( isdigit(ch))X=X*10+ch-48,ch=getchar();
return w?-X:X;
}
int ksm(int a,int b,int c){
int ans=1;
while(b){
if(b&1) ans=ans*a%c;
a=a*a%c;b>>=1;
} return ans;
}
void fj(int P){
int sq=sqrt(P);
for(int i=2;i<=sq;i++){
if(P%i==0){
c[++tot]=i;
while(P%i==0)
p[tot]++,P/=i;
p[tot]=ksm(i,p[tot],1e9+2);
}
} if(P!=1)
c[++tot]=P,p[tot]=P;
}
int solve(int x,int cur){
if(!x) return 1;
int now=1;
for(int i=2;i<p[cur];i++){
if(i%c[cur])
now=now*i%p[cur];
}
now=ksm(now,x/p[cur],p[cur]);
int q=x%p[cur];
for(int i=2;i<=q;i++){
if(i%c[cur])
now=now*i%p[cur];
}
return now*solve(x/c[cur],cur)%p[cur];
}
int C(int n,int m,int cur){
if(n<m) return 0;
if(n==m) return 1;
int now=0;
for(int i=n;i;i/=c[cur])
now+=i/c[cur];
for(int i=m;i;i/=c[cur])
now-=i/c[cur];
for(int i=n-m;i;i/=c[cur])
now-=i/c[cur];
int a=solve(n,cur),b=solve(m,cur),cc=solve(n-m,cur);
return a*inv(b,p[cur])%p[cur]*inv(cc,p[cur])%p[cur]*ksm(c[cur],now,p[cur])%p[cur];
}
int CRT(){
int ans=0;
for(int i=1;i<=tot;i++)
ans=(ans+a[i]*(P/p[i])*inv(P/p[i],p[i]))%P;
return ans;
}
signed main(){
P=getint();fj(P);
int n=getint(),m=getint(),cnt=0;
for(int i=1;i<=m;i++)
w[i]=getint(),cnt+=w[i];
if(cnt>n) return printf("Impossible"),0;
int ans=1,sum=n;
for(int i=1;i<=m;i++){
for(int j=1;j<=tot;j++)
a[j]=C(sum,w[i],j);
// printf("CRT=%lld
",CRT());
ans=ans*CRT()%P;
sum-=w[i];
} printf("%lld
",ans);
return 0;
}