zoukankan      html  css  js  c++  java
  • AGC021E Ball Eat Chameleons

    Link
    一只变色龙变成红色的要么是吃的红球比蓝球多,要么是吃的红球和蓝球一样多且最后一吃的是蓝球。
    设总共有(R)个红球和(B)个蓝球,若(R<B)则显然无解;若(R=B)则最后一个球一定是蓝球,其方案数等于(R)个红球与(B-1)个蓝球时的方案数。因此我们只需要考虑(R>B)的情况。
    (R-Bge n),那么我们可以让所有变色龙吃的红球都比蓝球多,因此任何一个序列都是合法的,方案数为({R+Bchoose R})
    (R-B<n),那么(n−R+B)只变色龙吃的红球和蓝球一样多,(R−B)只变色龙吃的红球比蓝球多一个(若存在合法方案,那么一定存在一个上述形式的合法方案,可以用调整法证明)。
    让吃的红球和蓝球一样多的变色龙都只吃一个红球和一个蓝球,剩下来的球不管以什么顺序吃都是合法的了。不难发现这是最优的构造方案。
    也就是说序列合法的充要条件是能够取出(n-R+B)对不交的RB子序列。
    这等价于对任意一个前缀而言,蓝球比红球多不超过(R-n)个。
    转化为格路计数问题即可,方案数为({R+Bchoose R}-{R+Bchoose 2R-n+1})

    #include<cstdio>
    const int N=500007,P=998244353;
    int fac[N],ifac[N];
    void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
    int mod(int x){return x+(x>>31&P);}
    int pow(int a,int b){int r=1;for(;b;b>>=1,a=1ll*a*a%P)if(b&1)r=1ll*a*r%P;return r;}
    int C(int n,int m){return n<m||m<0? 0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
    int main()
    {
        int n,k,ans=0;scanf("%d%d",&n,&k);
        for(int i=fac[0]=1;i<=k;++i) fac[i]=1ll*fac[i-1]*i%P;
        ifac[k]=pow(fac[k],P-2);for(int i=k;i;--i) ifac[i-1]=1ll*ifac[i]*i%P;
        for(int i=0,f;i+i<=k&&i+n<=k;++i) f=(i+i==k),inc(ans,mod(C(k-f,i-f)-C(k-f,i+i+n-k-1-f)));
        printf("%d",ans);
    } 
    
  • 相关阅读:
    Google Map API使用详解(三)——Google Map基本常识(上)
    Google Map API使用详解(十)——使用JavaScript创建地图详解(上)
    sethc.exe
    taobao_java
    "void __cdecl operator delete[](void *)" (??_V@YAXPAX@Z) 已经在 LIBCMTD.lib(delete2.obj) 中定义 错误
    some Content
    变参 C++ 转帖
    阅读大型程序你得到什么
    一些模块
    a common jsp
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12755355.html
Copyright © 2011-2022 走看看