首先orz PoPoQQQ。
不过后来想了一下好像不用crt合并那么麻烦。。。注意到当n>s时(s是一个很小的常数,应该在20~30左右),显然有n!的2的次数远远大于5的次数。那么这时5被2完全抵消之后,必然有2的次数>9,因此mod 512显然=0。那么大概就可以少一半的工作量啦?
不管了反正我抄Po爷代码。。
AC代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define mod1 512
#define mod2 1953125
using namespace std;
struct node{ ll x,y; }; ll n,m,k,pow1[2000005],pow2[2000005];
ll ksm(ll x,ll y,ll p){
ll t=1; for (; y; y>>=1,x=x*x%p) if (y&1) t=(ll)t*x%p;
return t;
}
node tms(node u,node v,ll p){
return (node){u.x*v.x%p,u.y+v.y};
}
node dvd(node u,node v,ll p,ll phi){
return (node){u.x*ksm(v.x,phi-1,p)%p,u.y-v.y};
}
node fct(ll x,ll p,ll q,ll *pw){
if (!x) return (node){1,0};
ll t=ksm(pw[q],x/q,q)*pw[x%q]%q;
return tms((node){t,x/p},fct(x/p,p,q,pw),q);
}
void write(ll x,ll k){
if (!k) return; write(x/10,k-1);
printf("%lld",x%10);
}
int main(){
scanf("%lld%lld%lld",&m,&n,&k);
pow1[0]=pow2[0]=1; int i;
for (i=1; i<=mod1; i++) pow1[i]=pow1[i-1]*((i&1)?i:1)%mod1;
for (i=1; i<=mod2; i++) pow2[i]=pow2[i-1]*((i%5)?i:1)%mod2;
node u=fct(m+n,2,mod1,pow1);
u=dvd(u,fct(m,2,mod1,pow1),mod1,mod1>>1);
u=dvd(u,fct(n,2,mod1,pow1),mod1,mod1>>1);
node v=fct(m+n,5,mod2,pow2);
v=dvd(v,fct(m,5,mod2,pow2),mod2,(mod2/5)<<2);
v=dvd(v,fct(n,5,mod2,pow2),mod2,(mod2/5)<<2);
ll t=min(u.y,v.y);
ll x=u.x*ksm(2,u.y-t,mod1)%mod1*ksm(205,t,mod1)%mod1;
ll y=v.x*ksm(5,v.y-t,mod2)%mod2*ksm(976563,t,mod2)%mod2;
ll ans=(x*212890625+y*787109376)%1000000000;
write(ans,k);
return 0;
}
by lych
2016.4.22