DreamGrid has just found two binary sequences s 1 , s 2 , … , s n s_1, s_2, \dots, s_n s1,s2,…,sn and t 1 , t 2 , … , t n t_1, t_2, \dots, t_n t1,t2,…,tn ( s i , t i ∈ { 0 , 1 } s_i, t_i \in \{0, 1\} si,ti∈{0,1} for all 1 ≤ i ≤ n 1 \le i \le n 1≤i≤n) from his virtual machine! He would like to perform the operation described below exactly twice, so that s i = t i s_i = t_i si=ti holds for all 1 ≤ i ≤ n 1 \le i \le n 1≤i≤n after the two operations.
The operation is: Select two integers l l l and r r r ( 1 ≤ l ≤ r ≤ n 1 \le l \le r \le n 1≤l≤r≤n), change s i s_i si to ( 1 − s i ) (1 - s_i) (1−si) for all l ≤ i ≤ r l \le i \le r l≤i≤r.
DreamGrid would like to know the number of ways to do so.
We use the following rules to determine whether two ways are different:
Let A = ( a 1 , a 2 , a 3 , a 4 ) A = (a_1, a_2, a_3, a_4) A=(a1,a2,a3,a4), where 1 ≤ a 1 ≤ a 2 ≤ n , 1 ≤ a 3 ≤ a 4 ≤ n 1 \le a_1 \le a_2 \le n, 1 \le a_3 \le a_4 \le n 1≤a1≤a2≤n,1≤a3≤a4≤n, be a valid operation pair denoting that DreamGrid selects integers a 1 a_1 a1 and a 2 a_2 a2 for the first operation and integers a 3 a_3 a3 and a 4 a_4 a4 for the second operation;
Let B = ( b 1 , b 2 , b 3 , b 4 ) B = (b_1, b_2, b_3, b_4) B=(b1,b2,b3,b4), where 1 ≤ b 1 ≤ b 2 ≤ n , 1 ≤ b 3 ≤ b 4 ≤ n 1 \le b_1 \le b_2 \le n, 1 \le b_3 \le b_4 \le n 1≤b1≤b2≤n,1≤b3≤b4≤n, be another valid operation pair denoting that DreamGrid selects integers b 1 b_1 b1 and b 2 b_2 b2 for the first operation and integers b 3 b_3 b3 and b 4 b_4 b4 for the second operation.
A A A and B B B are considered different, if there exists an integer k k k ( 1 ≤ k ≤ 4 1 \le k \le 4 1≤k≤4) such that a k ≠ b k a_k \ne b_k ak=bk.
Input
There are multiple test cases. The first line of the input contains an integer T T T, indicating the number of test cases. For each test case:
The first line contains an integer n n n ( 1 ≤ n ≤ 1 0 6 1 \le n \le 10^6 1≤n≤106), indicating the length of two binary sequences.
The second line contains a string s 1 s 2 … s n s_1s_2\dots s_n s1s2…sn ( s i ∈ { ’0’ , ’1’ } s_i \in \{\text{'0'}, \text{'1'}\} si∈{’0’,’1’}) of length n n n, indicating the first binary sequence.
The third line contains a string t 1 t 2 … t n t_1t_2\dots t_n t1t2…tn ( t i ∈ { ’0’ , ’1’ } t_i \in \{\text{'0'}, \text{'1'}\} ti∈{’0’,’1’}) of length n n n, indicating the second binary sequence.
It’s guaranteed that the sum of n n n in all test cases will not exceed 1 0 7 10^7 107.
Output
For each test case, output an integer denoting the answer.
Sample Input
3
1
1
0
2
00
11
5
01010
00111
Sample Output
0
2
6
Hint
For the second sample test case, there are two valid operation pairs: (1, 1, 2, 2) and (2, 2, 1, 1).
For the third sample test case, there are six valid operation pairs: (2, 3, 5, 5), (5, 5, 2, 3), (2, 5, 4, 4), (4, 4, 2, 5), (2, 4, 4, 5) and (4, 5, 2, 4).
题目大意:有两个01相同长度的01串,可以分别对两串执行一次操作,问有多少种方案使得两串在操作后相等。一次操作是指选取某个串的一个区间,将区间中的串按位取反。
解决方案:分情况讨论:
- 两个串初始是相等的。
那么此时,两次操作的区间要相同才能使操作后的两串相等。所以问题变成满足题意得 l , r l,r l,r有多少种不同得组合。 A n s = ( n ) + ( n − 1 ) + ⋯ + ( 1 ) = ( n + 1 ) ∗ n / 2 Ans=(n)+(n-1)+\cdots +(1)=(n+1)*n/2 Ans=(n)+(n−1)+⋯+(1)=(n+1)∗n/2 - 两个串初始只有一个连续的区间不同
那么此时,操作的目的就是把这段不同的区间变为相同。由于是01串,所以连续的不同的区间操作一次就相同了。设区间 [ x , y ] [x,y] [x,y]为不相同的区间,如下图所示。
由于不相同的区间只能操作一次,相同的区间必须呗操作0次或两次,设操作第一个串操作区间在左边,第二个在右边,那么,有三种操作类型。一是第一次操作覆盖 [ l , x ) [l,x) [l,x),第二次操作覆盖 [ l , y ] [l,y] [l,y],其中 1 ≤ l < x 1\leq l <x 1≤l<x,此时有 ( x − 1 ) (x-1) (x−1)种可能;二是第一次操作覆盖 [ x , r ] [x,r] [x,r],第二次操作覆盖 ( y , r ] (y,r] (y,r],其中 y < r ≤ n y<r\leq n y<r≤n,此时有 ( n − y + 1 − 1 ) (n-y+1-1) (n−y+1−1)种可能;三是第一次操作覆盖 [ x , m ] [x,m] [x,m],第二次操作覆盖 ( m , y ] (m,y] (m,y]此时有 ( y − x ) (y-x) (y−x)种可能。综合三种情况相加,共有 ( n − 1 ) (n-1) (n−1)中可能,根据对称性,第二次操作区间在第一次左边也是 ( n − 1 ) (n-1) (n−1)种可能,所以 A n s = 2 ∗ ( n − 1 ) Ans=2*(n-1) Ans=2∗(n−1)。
- 两个串有两个连续区间不相同。画个图数一数固定6种,和长度无关。
- 连续不同的区间超过2个。就两次操作机会,不可能还原的。
#include<iostream>
#include<vector>
using namespace std;
char s[1000010], t[1000010];
int T;
long long n;
int main() {
scanf("%d", &T);
while (T--) {
scanf("%lld", &n);
scanf("%s", s);
scanf("%s", t);
int Dif = 0, Length = 0;
bool flag = false;
for (int i = 0; i < n; ++i) {
if (s[i] == t[i]) {
if (Length != 0) {
++Dif;
Length = 0;
}
}
else {
++Length;
}
}
if (Length != 0) {
++Dif;
}
switch (Dif)
{
case 0: {
printf("%lld\n", n * (n + 1) / 2);
break;
}
case 1: {
printf("%lld\n", 2 * (n - 1));
break;
}
case 2: {
puts("6");
break;
}
default: {
puts("0");
break;
}
}
}
}