求C(n,k)%p
p是素数
1、1=
2、1<=n,k<=10^18,p<=10^7,直接用lucas定理;hdu3037 hdu3944
p不是素数
3、1=
4、1<=n,k<=10^18,P=p1^c1 * p2^c2 * p3^c3 * … *pt ^ ct,pi为素数,1≤pi^ci≤10^7。
先对每一个pi^ci求出去除p因子的结果以及pi的个数,再用拓展欧几里德求逆元,最后再乘以pi,对每一个结果用中国剩余定理合并。详见ACblog BZOJ2142 2012 Petr Mitrichev Contest 10-B
ACcode:
/**
FZU2020
*/
#include
#include
typedef long long LL;
const int MS=10010;
LL res,b;
int n,m,p,t,r,T;
int c[MS],cnt;
int isprime[MS],pri[MS],top=0;
void prepare()
{
for (int i=2;i0)
{
if (y&1) ans=(ans*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return ans;
}
int main()
{
prepare();
scanf("%d",&T);
while (T--)
{
scanf("%d%d%d",&n,&m,&p);
if ((n-m)
/**
hdu3398
*/
#include
#include
typedef long long LL;
const int NS=2000010;
const int MOD=20100501;
LL res;
int n,m,T;
int c[150000],cnt;
int isprime[NS],pri[150000],top=0;
void prime()
{
for (int i=2;i=r)
{
t/=r;
c[i]+=t*f;
}
}
cnt=cnt>i?cnt:i;
}
LL quick_pow(int a,int y)
{
LL ans=1,x=a;
while (y>0)
{
if (y&1) ans=(ans*x)%MOD;
x=(x*x)%MOD;
y>>=1;
}
return ans;
}
int main()
{
prime();
scanf("%d",&T);
while (T--)
{
cnt=0,res=1;
memset(c,0,sizeof(c));
scanf("%d %d",&n,&m);
factor(m,-1);
factor(n+m,1);
factor(n+1,-1);
int t=n-m+1;
for (int i=0;i
/**
hdu3037
*/
#include
#include
typedef long long LL;
LL res,b;
int n,m,p,n0,m0,T;
LL quick_pow(LL x,int y,int mod)
{
LL ans=1;
while (y)
{
if (y&1) ans=(ans*x)%mod;
x=(x*x)%mod;
y>>=1;
}
return ans;
}
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%d%d%d",&n,&m,&p);
res=1,n=n+m;
while (n>0||m>0)
{
n0=n%p,m0=m%p;
n/=p,m/=p;
if (n0
/**
hdu3944
*/
#include
#include
const int NS=9974;
int fac[NS][1229];
int isprime[NS],pri[NS],top=0;
void prepare()
{
memset(isprime,0,sizeof(isprime));
for (int i=2;i>=1)
{
if (y&1) ans*=x,ans%=mod;
x*=x,x%=mod;;
}
return ans;
}
int combin(int n,int k,int p)
{
int ans=1,x,y,q=isprime[p];
while (k>0)
{
x=n%p,y=k%p;
if (x
/**
BZOJ2142
*/
#include
#include
typedef long long LL;
const int NS=100010;
LL mod,sum,res;
int n,m;
int p[NS],q[NS],w[10],ac[NS];
int a[NS],c[NS],d[NS],cnt;
int isprime[NS],pri[NS],top=0;
void prime_table()
{
for (int i=2; i1) ret*=x-1;
return ret;
}
int quick_pow(int x,int y,int mo)
{
int ans=1;
while (y>0)
{
if (y&1) ans=((LL)ans*x)%mo;
x=((LL)x*x)%mo;
y>>=1;
}
return ans;
}
void divide(LL k)
{
int t,r;
for (int i=0; ipm) res=((LL)res*cal(k/pm,pos,flag))%y;
return res;
}
int exgcd(int a1,int a2,int &x,int &y)
{
if (!a2)
{
x=1,y=0;
return a1;
}
int r=exgcd(a2,a1%a2,x,y);
int t=x;
x=y,y=t-a1/a2*y;
return r;
}
int main()
{
int rem,res;
prime_table();
while (~scanf("%lld%d%d",&mod,&n,&m))
{
sum=cnt=0,res=1;
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
for (int i=0; in)
{
printf("Impossible\n");
continue;
}
divide(mod);
for (int i=0; i
/**
petr2012_B
*/
#include
#include
typedef long long LL;
const LL MOD2=1024;
const LL MOD5=9765625;
const LL MOD=10000000000LL;
LL n,m;
LL p[2],q[2],c[9];
int fac5[10000000],fac2[1111];
void prepare()
{
fac5[0]=fac2[0]=1;
for (int i=1;i>=1)
{
if (y&1) ans*=x,ans%=md;
x*=x,x%=md;
}
return ans;
}
LL cal(LL k,int flag,int z)
{
LL fd,x,ans;
int md,y,r;
md=flag?MOD5:MOD2;
r=k%md,x=k/md;
if (flag) y=5,fd=fac5[md-1],ans=fac5[r];
else y=2,fd=fac2[md-1],ans=fac2[r];
ans=(ans*qpow(fd,x,md))%md;
c[flag]+=k/y*z;
if (k>y) ans=(ans*cal(k/y,flag,z))%md;
return ans;
}
LL Exgcd(LL a,LL b,LL &x,LL &y)
{
if (!b)
{
x=1,y=0;
return a;
}
LL r=Exgcd(b,a%b,x,y);
LL t=x;
x=y,y=t-a/b*y;
return r;
}
int main()
{
freopen("combi.in","r",stdin);
freopen("combi.out","w",stdout);
prepare();
while (~scanf("%I64d%I64d",&n,&m))
{
c[0]=c[1]=0;
p[0]=cal(n,0,1);
q[0]=cal(n-m,0,-1);
q[0]*=cal(m,0,-1);
p[1]=cal(n,1,1);
q[1]=cal(n-m,1,-1);
q[1]*=cal(m,1,-1);
q[0]%=MOD2,q[1]%=MOD5;
LL x,y,res;
Exgcd(q[0],MOD2,x,y);
p[0]=(p[0]*x%MOD2+MOD2)*qpow(2,c[0],MOD2)%MOD2;
Exgcd(q[1],MOD5,x,y);
p[1]=(p[1]*x%MOD5+MOD5)*qpow(5,c[1],MOD5)%MOD5;
Exgcd(MOD2,MOD5,x,y);
res=p[0]*(y*MOD5%MOD)%MOD;
Exgcd(MOD5,MOD2,x,y);
res=(res+p[1]*(y*MOD2%MOD)+MOD)%MOD;
x=1;
double s=1;
int flag=0;
if (n-m=MOD)
{
flag=1;
break;
}
}
if (flag) printf("...%010I64d\n",res);
else printf("%I64d\n",res);
}
return 0;
}