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
题意:给你一个长度为n的01字符串,问能找出多少个三元组(i,j,k)满足ch[j]==1&&i<j<k&&F(i,j)==F(j,k)(F(x,y)表示区间[x,y]中字符1的个数)
解题思路:可以先将问题转换为有多少个区间中1的个数为奇数,这个可以dp解决,然后减去字符1在最左端,右边全为0的和字符在最右端,左边全为1的即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
const int maxn = 200000 + 10;
char ch[maxn];
int L[maxn], R[maxn], n;
long long dp[maxn][2];
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
scanf("%s", ch + 1);
L[0] = R[n + 1] = dp[0][0] = dp[0][1] = 0;
for (int i = 1; i <= n; i++)
{
if (i > 1 && ch[i - 1] == '1') L[i] = 1;
else L[i] = L[i - 1] + 1;
}
for (int i = n; i >= 1; i--)
{
if (i < n && ch[i + 1] == '1') R[i] = 1;
else R[i] = R[i + 1] + 1;
}
LL ans = 0;
for (int i = 1; i <= n; i++)
{
if (ch[i] == '1')
{
dp[i][0] = dp[i - 1][1];
dp[i][1] = dp[i - 1][0] + 1;
}
else
{
dp[i][0] = dp[i - 1][0] + 1;
dp[i][1] = dp[i - 1][1];
}
ans = ans + dp[i][1];
}
for (int i = 1; i <= n; i++)
{
if (ch[i] == '1')
{
ans = ans - (L[i] - 1);
ans = ans - (R[i] - 1);
ans--;
}
}
printf("%lld\n", ans);
}
return 0;
}