记录编号 |
449345 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[国家集训队2011]礼物(魏铭) |
最终得分 |
100 |
用户昵称 |
FoolMike |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
0.045 s |
提交时间 |
2017-09-14 07:52:39 |
内存使用 |
7.92 MiB |
显示代码纯文本
- #include<cstdio>
- #include<algorithm>
- using namespace std;
- typedef long long ll;
- int power(int x,int y,int p){
- int ans=1;
- for (;y;y>>=1,x=1ll*x*x%p)
- if (y&1) ans=1ll*ans*x%p;
- return ans;
- }
- int getpow(int x,int p){
- return x>=p?getpow(x/p,p)+x/p:0;
- }
- int n,m,p,cnt,prime[20],pow[20];
- void factor(int p){
- for (int i=2;i*i<=p;i++)
- if (p%i==0){
- prime[++cnt]=i;
- while (p%i==0) pow[cnt]++,p/=i;
- }
- if (p>1) prime[++cnt]=p,pow[cnt]=1;
- }
- const int N=1e5+10;
- struct _mod{
- int jc[N],p,mod;
- void init(int P,int Mod){
- p=P;mod=Mod;
- jc[0]=1;
- for (int i=1;i<mod;i++) jc[i]=1ll*jc[i-1]*(i%p?i:1)%mod;
- }
- int calc(int n){//求n!%mod
- return n>=p?1ll*jc[n%mod]*power(jc[mod-1],n/mod,mod)%mod*calc(n/p)%mod:jc[n];
- }
- }base[20];
- int mi[20],res[20],mod[20],phi[20];
- void del(int x){
- for (int i=1;i<=cnt;i++){
- int r=base[i].calc(x);
- mi[i]-=getpow(x,prime[i]);
- res[i]=1ll*res[i]*power(r,phi[i]-1,mod[i])%mod[i];
- }
- }
- int main()
- {
- freopen("nt2011_gift.in","r",stdin);
- freopen("nt2011_gift.out","w",stdout);
- scanf("%d%d%d",&p,&n,&m);
- factor(p);
- for (int i=1;i<=cnt;i++){
- mod[i]=1;
- for (int j=0;j<pow[i];j++) mod[i]*=prime[i];
- phi[i]=mod[i]/prime[i]*(prime[i]-1);
- base[i].init(prime[i],mod[i]);
- mi[i]=getpow(n,prime[i]);
- res[i]=base[i].calc(n);
- }
- ll sum=0;
- for (int i=1;i<=m;i++){
- int x;
- scanf("%d",&x);
- sum+=x;del(x);
- }
- if (n<sum) return puts("Impossible"),0;
- del(n-sum);
- ll ans=0;
- for (int i=1;i<=cnt;i++){
- res[i]=1ll*res[i]*power(prime[i],mi[i],mod[i])%mod[i];
- int P=p/mod[i];
- ans=(ans+1ll*res[i]*P*power(P,phi[i]-1,mod[i]))%p;
- }
- printf("%lld\n",ans);
- return 0;
- }