[BZOJ3392]序列计数

来源:互联网 发布:软件风险有哪些 编辑:程序博客网 时间:2024/06/08 00:21
题目描述


输入

两个整数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-invertLL 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;}

原创粉丝点击