The great dog detective Sherlock Bones is on the verge of a new discovery. But for this problem, he needs the help of his most trusted advisor -you- to help him fetch the answer to this case.
He is given a string of zeros and ones and length N.
Let F(x, y) equal to the number of ones in the string between indices x and y inclusively.
Your task is to help Sherlock Bones find the number of ways to choose indices (i, j, k) such that i < j < k, sj is equal to 1, and F(i, j) is equal to F(j, k).
The first line of input is T – the number of test cases.
The first line of each test case is an integer N (3 ≤ N ≤ 2 × 105).
The second line is a string of zeros and ones of length N.
For each test case, output a line containing a single integer- the number of ways to choose indices (i, j, k).
3 5 01010 6 101001 7 1101011
2 3 7
题意:定义f(i,j)为[i,j]中1的个数 找出有多少三元组 f(i,j)=f(j,k)且i<j<k且a[j]=1
题解:
定义dp[0][0]为不取前一位的和 mod 2=0的情况 dp[1][0]为取前一位的和 mod 2=0的情况
dp[1][0]为不取前一位的和 mod 2=1的情况 dp[1][1]为取前一位的和 mod 2=1的情况
dp搞一搞 然后去掉 100000000 000000001 1 这些情况
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll dp[2][2];
char s[200005];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,i,j;
scanf("%d",&n);
memset(dp,0,sizeof(dp));
scanf("%s",s+1);
for(i=1;i<=n;i++){
if(s[i]=='0'){
dp[0][0]+=dp[0][1];
dp[1][0]+=dp[1][1];
dp[0][1]++;
}
else{
dp[0][0]+=dp[0][1];
dp[1][0]+=dp[1][1];
swap(dp[1][1],dp[0][1]);
dp[1][1]++;
}
}
ll ans=dp[1][0]+dp[1][1];
for(i=1;i<=n;i++){
if(s[i]=='1'){
ans--;
int now=i-1;
while(s[now]=='0'&&now>=1){
ans--;
now--;
}
now=i+1;
while(s[now]=='0'&&now<=n){
ans--;
now++;
}
}
}
printf("%lld\n",ans);
}
return 0;
}