题目描述
输入
两个整数m和k
输出
输出一个整数
样例输入
5 3
样例输出
10
数据规模
来源 by azui
题解:
以样例为例,排列为0 0 0 0 0,0 0 0 0 1,0 0 0 1 1,0 0 1 1 1,0 1 1 1 1,1 1 1 1 1,1 1 1 1 2,1 1 1 2 2,1 1 2 2 2,1 2 2 2 2,2 2 2 2 2, 2 2 2 2 3......
呈周期性变化。用组合数解决。
扩展欧几里得版:
#include<cstdio> typedef long long LL; const LL Mod=998244353; void Exgcd( LL a, LL b, LL &x, LL &y ) { if( !b ) { x=1; y=0; } else { Exgcd( b, a%b, y, x ); y-=(a/b)*x; } } LL Fac( LL w ) { LL res=1; for( LL i=2; i<=w; i++ ) res=i%Mod*res%Mod; return res; } LL Inv( LL w ) {//求w!的逆元 LL x, y; LL jc=Fac(w); Exgcd( jc, Mod, x, y ); return ( x+Mod )%Mod; } LL C( LL n, LL m ) { LL a=Inv(m); LL b=Inv(n-m); LL jc=Fac(n); return jc*a%Mod*b%Mod; } LL m, k; int main() { scanf( "%I64d%I64d", &m, &k ); printf( "%I64d\n", C( m, (k-1)%m ) ); return 0; }
线性求逆元版:
#include<cstdio> typedef long long LL; const LL Mod=998244353; void Exgcd( LL a, LL b, LL &x, LL &y ) { if( !b ) { x=1; y=0; } else { Exgcd( b, a%b, y, x ); y-=(a/b)*x; } } LL Fac( LL w ) { LL res=1; for( LL i=2; i<=w; i++ ) res=i%Mod*res%Mod; return res; } LL Inv( LL w ) { if( w==1 ) return 1; return ( Mod-Mod/w*Inv( Mod%w )%Mod )%Mod; } //可参考http://blog.miskcoo.com/2014/09/linear-find-all-invert LL C( LL n, LL m ) { LL a=Inv( Fac(m) ); LL b=Inv( Fac(n-m) ); LL c=Fac(n); return a*b%Mod*c%Mod; } LL m, k; int main() { scanf( "%lld%lld", &m, &k ); printf( "%lld\n", C( m, (k+m-1)%m ) ); return 0; }
[BZOJ3392]序列计数
最新推荐文章于 2021-09-12 00:50:41 发布