Educational Codeforces Round 93 (Rated for Div. 2) C题解

这个问题的意思就是让你找到一个区间内所有元素和等于区间长度的区间数量。

我们可以先把所有元素先减去1,这样得到的符合条件的区间内元素和0,题意也就变成了找所有和为0区间的数量。若采取暴力做法,题目数据是1e5,时间复杂度是O(n*n)会超时。这时候就要用到stl中的map来优化。

如果两个前缀和相等,则说明这两个前缀和之间的元素和为零,其中所有和为零的区间数为n*(n-1)/2,这里要给前缀和为0的一个特判,前缀和为零的有几个就说明有几个数为0,只需直接先将map[0]加一即可。用map来记各个前缀和的数量非常方便快捷。由于数据范围较大,这题答案要用longlong 类型,得出答案的表达式中的n也要用longlong 不然会超int范围导致答案错误。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
typedef long long ll;

map<ll,ll> m;
int s[N];
int t;
ll ans;

int main()
{
    cin >> t;
    while(t --)
    {
        ans = 0;

        int n;

        cin >> n;
        
        string str;

        cin >> str;

        for(int i = 1; i <= n; i ++)    s[i] = s[i - 1] + str[i - 1] - '1';

        m[0] ++;
        for(int i = 1; i <= n; i ++)    m[s[i]] ++;

        for(auto it : m)
        {
            ans += it.second * (it.second - 1)/2;
        }
        printf("%lld\n", ans);
        m.clear();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值