2015 ICL, Finals, Div. 1 Ceizenpok’s formula(组合数取模,扩展lucas定理+中国剩余定理)

来源:互联网 发布:网络电影播放器排行榜 编辑:程序博客网 时间:2024/06/06 12:27

J. Ceizenpok’s formula
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Dr. Ceizenp'ok from planet i1c5l became famous across the whole Universe thanks to his recent discovery — the Ceizenpok’s formula. This formula has only three arguments: nk and m, and its value is a number of k-combinations of a set of n modulo m.

While the whole Universe is trying to guess what the formula is useful for, we need to automate its calculation.

Input

Single line contains three integers nkm, separated with spaces (1 ≤ n ≤ 10180 ≤ k ≤ n2 ≤ m ≤ 1 000 000).

Output

Write the formula value for given arguments nkm.

Sample test(s)
input
2 1 3
output
2
input
4 2 5
output
1

评测链接:http://codeforces.com/gym/100633/problem/J


解析:首先,将m做质因数分解:m=p1*p2*p3。。。。(pi=ai^ti)

      然后用扩展lucas定理求解:b[i]=c(n,m)%pi

      然后用中国剩余定理进行合并,即可得解。

代码:

#include<cstdio>using namespace std;typedef long long LL;LL pow_mod(LL x,LL y,LL p){  LL ans=1;  while(y>0)    {      if(y&1)ans=ans*x%p;      x=x*x%p,y>>=1;}  return ans;}LL c1(LL n,LL p,LL pk){  if(n==0)return 1;  LL i,j,k,ans=1;  for(i=2;i<=pk;i++)if(i%p)ans=ans*i%pk;  ans=pow_mod(ans,n/pk,pk);  for(k=n%pk,i=2;i<=k;i++)if(i%p)ans=ans*i%pk;  return ans*c1(n/p,p,pk)%pk;}LL reverse(LL a,LL m){  if(a==0)return 0;  LL y=0,x=1,r=a%m,q,t,mm=m;  if(r<0)r+=m;  while((m%r)!=0)    {      a=m,m=r,q=a/m,r=a%m;      t=x,x=y-x*q,y=t;}  if(r!=1)return 0;  if(x<0)x+=mm;  return x;}LL cal(LL n,LL m,LL p,LL pi,LL pk){  LL i,j,k=0,a,b,c,ans;  a=c1(n,pi,pk),b=c1(m,pi,pk),c=c1(n-m,pi,pk);  for(i=n;i;i/=pi)k+=i/pi;  for(i=m;i;i/=pi)k-=i/pi;  for(i=n-m;i;i/=pi)k-=i/pi;  ans=a*reverse(b,pk)%pk*reverse(c,pk)%pk*pow_mod(pi,k,pk)%pk;  return ans*(p/pk)%p*reverse(p/pk,pk)%p;}int main(){  LL n,m,p,ans=0,x,i,j,k;  scanf("%I64d%I64d%I64d",&n,&m,&p);  for(x=p,i=2;x>1;i++)if(x%i==0)    {      for(k=1;x%i==0;x/=i)k*=i;      ans=(ans+cal(n,m,p,i,k))%p;}  printf("%I64d\n",ans);}

  

0 0
原创粉丝点击