HNOI2017 抛硬币
来源:互联网 发布:淘宝手机端复制链接 编辑:程序博客网 时间:2024/05/16 08:09
题解
实际上就是要求
直接算显然会超时,考虑优化。注意到
对于
SRC
#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std ;#define N 100 + 10#define M 2000000 + 10typedef 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 ;}
以上.
1 0
- HNOI2017 抛硬币
- 4830: [Hnoi2017]抛硬币
- [组合数取模] BZOJ 4830 [Hnoi2017]抛硬币
- [BZOJ4830][HNOI2017]抛硬币-扩展Lucas定理
- HNOI2017滚粗记
- HNOI2017滚粗记
- hnoi2017滚粗记
- [HNOI2017]影魔
- HNOI2017 影魔
- HNOI2017 礼物
- HNOI2017总结
- 抛硬币游戏模拟
- 抛硬币问题
- 抛硬币问题
- 抛硬币的模拟
- 随机抛硬币
- CSU 1009 抛硬币
- 抛硬币问题
- man指令
- 递归算法之阶乘算法
- 在linux环境下编译运行OpenCV程序的两种方法
- 常用开发资源整理(更新日:2017/4/26)
- man手册
- HNOI2017 抛硬币
- P1341 地震逃生
- 已经转到自己搭建的博客了
- SpringMVC框架学习笔记
- 学习使用ITIL/ITSM规范来指导IT技术管理工作
- java集合系列03 AbstractCollection
- 解决IEM被禁用的问提
- Altium Designer原理图设计
- 常用的键盘值