A-Sherlock Bones

https://codeforces.com/gym/323862/problem/A
————————————————————————————————————
1111111==>11101111
添加的0会对组数造成增多的影响
如果中心1在0左边,则会使右边的连串0对左侧1造成影响(增多0的个数种选择数)
反之亦然
————————————————————————————————————
思路:
开数组记录每个1前面0的个数L,与每个1后面0的个数R,
对于第i个位置:种类数L(i)xR(i)+∑(L(i-a)+1)x(R(i-a)+1)
然而这样会超时
————————————————————————————————————
优化:
把L与R全部+1
发现奇与奇相乘,偶与偶相同。
对于一个七个1的序列:
L1x(R3+R5+R7)+
L3x(R5+R7)+
L5x(R7)
偶数同理
所以维护一个后缀和
取L[i] x sum[i+2]

#include<bits/stdc++.h>
using namespace std;
long long l[200500],r[200500];  //1左侧0的数量与右侧0的数量
long long s[200500];    //奇偶前缀和
void ope(){
    long long ans=0;
    int n;
    int j,o;//奇偶右端点
    int num=1;//1的总个数
    char t;
    cin>>n;
    memset(l,0,sizeof l);
    memset(r,0,sizeof r);
    memset(s,0,sizeof s);
    for(int i=0;i<n;i++){   //记录左侧1的个数
        cin>>t;
        if(t=='0'){
            l[num]++;
        }else{
            num++;
        }
    }
    num--;
    for(int i=0;i<=num;i++){    //这里一定要从0开始,不然l[1]不会+1,答案会错
        l[i+1]++;
        r[i]=l[i+1];
    }
    for(int i=1;i<=num;i++){    //先把只有自己一个1的情况算进去
        ans+=(l[i]-1)*(r[i]-1);
    }
    for(int i=num;i>0;i--){ //处理一个后缀和
        s[i]=s[i+2]+r[i];
    }
    for(int i=1;i<=num;i++){    //左侧乘右侧的后缀和
        ans+=l[i]*s[i+2];   
    }
    cout<<ans<<endl;
    return;
}
int main(){
    int n;
    cin>>n;
    while(n--){
        ope();
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值