实际上就是要求 ∑a+bi=b+1Cia+b ,组合数取模即可。
直接算显然会超时,考虑优化。注意到 ∑ni=0Cin=2n ,而且 Cin 是对称的。所以对于 a+b 为奇数的情况,直接用 2a+b/2=2a+b−1 计算出 ∑ni=⌈a+b2⌉Cia+b ,剩下 ∑⌊a+b2⌋i=b+1Cia+b 可以直接暴力计算。
对于 a+b 为偶数的情况,需要特殊处理一下中间的边界。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std ;
#define N 100 + 10
#define M 2000000 + 10
typedef long long ll ;
ll Tab[N] , f[2][M] ;
ll a , b , k , MO ;
int P = 1e9 ;
int ans ;
ll Power( ll x , ll k , int MO ) {
ll s = 1 ;
while ( k ) {
if ( k & 1 ) s = s * x % MO ;
x = x * x % MO ;
k /= 2 ;
}
return s ;
}
ll Count( ll n , int p ) { return n == 0 ? 0 : n / p + Count( n / p , p ) ; }
ll fac( ll n , int p ) {
if ( n == 0 ) return 1 ;
ll ret = 1 ;
int t = p == 2 ? 0 : 1 ;
if ( n >= MO ) ret = f[t][MO] ;
ret = Power( ret , n / MO , MO ) ;
ret = ret * f[t][n%MO] % MO ;
return ret * fac( n / p , p ) % MO ;
}
ll phi( ll p , ll pk ) { return pk / p * (p - 1) ; }
ll Calc( ll n , ll m ) {
ll ret = 1 ;
MO = Power( 2 , 9 , P ) ;
ll k = Count( n , 2 ) - Count( m , 2 ) - Count( n - m , 2 ) ;
ll a1 = 0 ;
if ( k < 9 ) a1 = Power( 2 , k , MO ) * fac( n , 2 ) % MO * Power( fac( m , 2 ) * fac( n - m , 2 ) % MO , phi( 2 , MO ) - 1 , MO ) % MO ;
ret = (P / MO) * Power( P / MO , phi( 2 , MO ) - 1 , MO ) % P * a1 % P ;
MO = Power( 5 , 9 , P ) ;
k = Count( n , 5 ) - Count( m , 5 ) - Count( n - m , 5 ) ;
ll a2 = 0 ;
if ( k < 9 ) a2 = Power( 5 , k , MO ) * fac( n , 5 ) % MO * Power( fac( m , 5 ) * fac( n - m , 5 ) % MO , phi( 5 , MO ) - 1 , MO ) % MO ;
ret = (ret + (P / MO) * Power( P / MO , phi( 5 , MO ) - 1 , MO ) % P * a2 % P) % P ;
return ret ;
}
ll Calc2( ll n , ll m ) {
ll ret = 1 ;
MO = Power( 2 , 9 , P ) ;
ll k = Count( n , 2 ) - Count( m , 2 ) - Count( n - m , 2 ) - 1 ;
ll a1 = 0 ;
if ( k < 9 ) a1 = Power( 2 , k , MO ) * fac( n , 2 ) % MO * Power( fac( m , 2 ) * fac( n - m , 2 ) % MO , phi( 2 , MO ) - 1 , MO ) % MO ;
ret = (P / MO) * Power( P / MO , phi( 2 , MO ) - 1 , MO ) % P * a1 % P ;
MO = Power( 5 , 9 , P ) ;
k = Count( n , 5 ) - Count( m , 5 ) - Count( n - m , 5 ) ;
ll a2 = 0 ;
if ( k < 9 ) a2 = Power( 5 , k , MO ) * fac( n , 5 ) % MO * Power( fac( m , 5 ) * fac( n - m , 5 ) % MO , phi( 5 , MO ) - 1 , MO ) % MO ;
a2 = a2 * Power( 2 , phi( 5 , MO ) - 1 , MO ) % MO ;
ret = (ret + (P / MO) * Power( P / MO , phi( 5 , MO ) - 1 , MO ) % P * a2 % P) % P ;
return ret ;
}
int main() {
freopen( "coin.in" , "r" , stdin ) ;
freopen( "coin.out" , "w" , stdout ) ;
Tab[0] = 1 ;
for (int i = 1 ; i <= 9 ; i ++ ) Tab[i] = Tab[i-1] * 10 ;
f[0][0] = f[1][0] = 1 ;
int UP = Power( 2 , 9 , P ) ;
for (int i = 1 ; i <= UP ; i ++ ) {
f[0][i] = f[0][i-1] ;
if ( i & 1 ) f[0][i] = f[0][i] * i % UP ;
}
UP = Power( 5 , 9 , P ) ;
for (int i = 1 ; i <= UP ; i ++ ) {
f[1][i] = f[1][i-1] ;
if ( i % 5 ) f[1][i] = f[1][i] * i % UP ;
}
while ( scanf( "%lld%lld%lld" , &a , &b , &k ) != EOF ) {
ans = Power( 2 , a + b - 1 , P ) ;
if ( (a + b) & 1 ) {
for (ll i = b + 1 ; i <= (a + b) / 2 ; i ++ ) ans = (ans + Calc( a + b , i )) % P ;
} else {
ans = ((ans - Calc2( a + b , (a + b) / 2 )) % P + P) % P ;
for (ll i = b + 1 ; i <= (a + b) / 2 ; i ++ ) ans = (ans + Calc( a + b , i )) % P ;
}
ans %= Tab[k] ;
if ( k == 1 ) printf( "%d\n" , ans ) ;
if ( k == 2 ) printf( "%02d\n" , ans ) ;
if ( k == 3 ) printf( "%03d\n" , ans ) ;
if ( k == 4 ) printf( "%04d\n" , ans ) ;
if ( k == 5 ) printf( "%05d\n" , ans ) ;
if ( k == 6 ) printf( "%06d\n" , ans ) ;
if ( k == 7 ) printf( "%07d\n" , ans ) ;
if ( k == 8 ) printf( "%08d\n" , ans ) ;
if ( k == 9 ) printf( "%09d\n" , ans ) ;
}
return 0 ;
}
以上.