Problem - C - Codeforces
翻译:
给定一个数组𝑎1,𝑎2,…,𝑎𝑛,由0到9的整数组成。一子数组𝑎𝑙,𝑎𝑙+ 1,𝑎𝑙+ 2,…,𝑎𝑟−1,𝑎𝑟很好如果这个子数组的元素之和等于这个子数组的长度(∑𝑖=𝑙𝑟𝑎𝑖=𝑟−𝑙+ 1)。
例如,如果𝑎=(1 2 0),然后有3好子阵:𝑎1…1 =[1],𝑎2…3 =(2,0)和𝑎1…3 =(1 2 0)。
计算数组𝑎的好子数组的数量。
输入
第一行包含一个整数𝑡(1≤𝑡≤1000)——测试用例的数量。
每个测试用例的第一行包含一个整数𝑛(1≤𝑛≤105)——数组𝑎的长度。
每个测试用例的第二行包含一个由𝑛十进制数字组成的字符串,其中𝑖-th数字等于𝑎𝑖的值。
可以保证所有测试用例中𝑛的总和不超过105。
输出
对于每个测试用例,打印一个整数——数组𝑎的好子数组的数量。
例子
inputCopy
3.
3.
120
5
11011
6
600005
outputCopy
3.
6
1
请注意
语句中考虑第一个测试用例。
在第二个测试用例,有6好子阵:𝑎1…1,𝑎2…2,𝑎1…2,𝑎4…4,𝑎5…5和𝑎4…5。
在第三个测试用例中,只有一个好的子数组:𝑎2…
思路:
区间和等于区间长度,我们将其转化成为前缀和,那就是s[r]-s[l]=r-l+1,将其每次减1,那么就是s[r]-r=s[l]-l,所以就是相同的前缀然后其中取两个就好了。
代码:
/*Looking! The blitz loop this planet to search way
Only my RAILGUN can shoot it 今すぐ
身体中を 光の速さで
駆け巡った確かな予感
掴め! 望むものなら残さず
輝ける自分らしさで
信じてるよ あの日の誓いを
この瞳に光る涙それさえも 強さになるから
*/
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long ll;
int n,t;
inline __int128 read(){
__int128 x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){
if(ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
inline void print(__int128 x){
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
print(x / 10);
putchar(x % 10 + '0');
}
int a[100005];
ll s[100005];
char ss;
void wanyurukong(){
cin>>n;
ll an=0;
map<ll,ll>q;
for (int i=1; i<=n; i++) {
cin>>ss;
a[i]=ss-'0';
}
q[0]=1;
for (int i =1; i<=n; i++) {
s[i]=s[i-1]+a[i]-1;
q[s[i]]++;
}
for(auto x:q){
an+=x.second*(x.second-1)/2;
}
printf("%lld\n",an);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(); cout.tie();
cin>>t;
while (t--) {
wanyurukong();
}
//wanyurukong
return 0;
}