AquaMoon and Chess_CodeForces - 1545B

由110变成011,由011变成110,“11”的组合和0可以交换位置

如果是1110 或者是 1110 的情况,红色的“11”与0换位置,变成1011,可以看成蓝色的“11”到了0的后面,蓝色“11”和0的相对位置改变了,而第三个“1”是被动的,他起到了完成蓝色“11”和0换相对位置的桥梁的作用

因此,单独的“1”起到了交换“11”和“0”的桥梁作用,其自身是被动的

比如1100010,等到“11”换到这个情况:0001110 的时候,红色的1让“11”可以与最后一个0交换相对位置

那结果就是C(a+b,a) a是"11"组合的个数,b是0的个数

#include<bits/stdc++.h>
using namespace std;
using ll=long long ;

const ll maxn=1e5+5,N=1e5,mod=998244353;
ll fact[maxn],inv[maxn],vis[maxn];

ll bin_pow(ll a,ll n){
    ll res=1;
    a=a%mod;
    while(n){
        if(n&1) res=res*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return res;
}

ll com(ll n,ll m){
    if(m>n || m<0) return 0;
    if(n==m || m==0) return 1;
    ll ans=fact[n]*inv[m]%mod*inv[n-m]%mod;
    return ans;
}

int main()
{
    ios::sync_with_stdio(0);cin.tie(0);
    freopen("D:\\in.txt","r",stdin);

    //预处理1到1e5的阶乘和逆元
    fact[0]=1;
    for(ll i=1;i<=N;i++){
        fact[i]=fact[i-1]*i%mod;
        inv[i]=bin_pow(fact[i],mod-2);
    }

    ll kase=0;
    ll T;cin>>T;
    while(T--){
        kase++;
        ll n;cin>>n;
        string s;cin>>s;
        ll a=0,b=0;
        for(ll i=0;i<s.size();i++){
            if(s[i]=='0') a++;
            else if(s[i]=='1' && i>0) {
                if(s[i-1]=='1' && vis[i-1]!=kase){
                    vis[i]=vis[i-1]=kase;
                    b++;
                }
            }
        }
        //printf("a=%lld b=%lld\n",a,b);
        cout<<com(a+b,a)<<"\n";
    }
    return 0;
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值