题目
有人讲得比我好
嗯,总的来说就是把情况通过反转每一位的值来建立一一映射。
建立映射之后就可以简单+不能建立映射的方案再/2了,
这个题对于2的逆元的处理十分巧妙,也可以当做一个不错的
板题。
#include<bits/stdc++.h>
#define LL long long
#define mod 1000000000
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
using namespace std;
void exgcd(int a,int b,int &x,int &y,int &gcd){ !b?(x=1,y=0,gcd=a):(exgcd(b,a%b,y,x,gcd),y-=a/b*x); }
struct factory{
int fac[1953125],P,Pr;
void init(int p,int pr){ fac[0]=1,P=p,Pr=pr;rep(i,1,p-1) fac[i]=i%pr?1ll*fac[i-1]*i%P:fac[i-1]; }
int Pow(int b,int k){ int r=1;for(;k;k>>=1,b=1ll*b*b%P) if(k&1)r=1ll*r*b%P;return r; }
int INV(int u){ int x,y,gd;exgcd(u,P,x,y,gd);return x; }
int F(LL n){ return n?F(n/Pr)*1ll*fac[n%P]%P*Pow(fac[P-1],n/P)%P:1; }
int C(LL n,LL m){
int k=0;for(LL t=n;t;t/=Pr) k+=t/Pr;
for(LL t=m;t;t/=Pr) k-=t/Pr;for(LL t=n-m;t;t/=Pr) k-=t/Pr;
if(k >= 9) return 0;
return 1ll * F(n) * INV(F(m)) % P * INV(F(n-m)) % P * Pow(Pr,k) % P;
}
}f2,f5;
int C(LL n,LL m){
int a=f2.C(n,m),b=f5.C(n,m),x,y,gd;
exgcd(512,1953125,x,y,gd);
return (a + 512ll * x % mod * (b-a)) % mod;
}
int Pow(int b,LL k){ int r=1;for(;k;k>>=1,b=1ll*b*b%mod) if(k&1) r=1ll*r*b%mod;return r; }
void print(int a,int k){ for(;k--;) printf("%d",a/Pow(10,k)%10);puts(""); }
int main(){
LL a,b,k;
f2.init(512,2),f5.init(1953125,5);
for(;~scanf("%lld%lld%d",&a,&b,&k);){
if(a == b) print((Pow(2,a+b-1)-C(2*a-1,a))%mod+mod,k);
else{
int ans = (Pow(2,a+b-1) + ((!((a+b)&1)) ? C(a+b-1,(a+b)/2) : 0)) % mod;
rep(j,1,(a-b-1)/2) ans = (ans + C(a+b,b+j)) % mod;
print((ans+mod)%mod,k);
}
}
}