题目来源: Educational Codeforces Round 93 (Rated for Div. 2)-C
题意:
给定一个仅由数字0-9构成的序列,计算数字和等于区间长度的区间数。
思路:
区间数字和等于区间长度,等价于将所有数字减一后,区间数字和为零。这将本题目的转化为了:求数字和为零的区间数。
通过前缀和表示和为零,两段的前缀和相等,则其差值和为零。
用map记录当前前缀和出现的次数,每次加上该值即可,例子如下:假设前5位和为x,前8位和也为x,则可以判断第6位到第8位和为0,贡献为1;若第10位也为x,则第6位到第10位、第9位到第10位和仍为x,贡献为2。
代码:
#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <functional>
#include <string>
#include <cstring>
#include <sstream>
#include <deque>
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<P,int> Q;
const int inf1=1e9+9;
const ll inf2=1e16+9;
const ll mol=1e9+7;
const int maxn=5e4+9;
const ll maxx=1e12+9;
int n;
string s;
map<int,int> mp;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cin>>n>>s;
int sum=0;
ll ans=0;
mp.clear(); mp[0]=1;
for(int i=0;i<n;i++)
{
sum+=s[i]-'0'-1;
ans+=mp[sum];
mp[sum]++;
}
printf("%lld\n",ans);
}
}