1. 程式人生 > >2018青島區域賽C:Flippy Sequence

2018青島區域賽C:Flippy Sequence

 

 題意:找出l,r在此區域內的所有數0變為1,1變為0,進行兩次操作,問一共有多少種方法。

兩個串相同就是兩個串的異或值為0

把兩個串異或,

找出連續的1的有多少塊。

1.兩塊以上的無法用兩次操作達到效果,所以為0

2.全為1的有(n-1)*2種,因為要把所有的1變成0,所以只要把串分為兩部分,明顯有(1,1,2, n)(1,2,3,n-2).....

(1,n-1,n,n),一共n-1種,反過來又有n-1種。

3.全為0的需要把一段串改變兩次,選一個有n種,選兩個有n-1種......選n個有一種,因為是相同的,所以不能反過來。有n(n+1)/2。

4.有兩塊連續的1的情況,一共只有6種情況,兩塊1分兩次改變為一次,左邊連續的1和中間的0改變一次再把右邊連續的1和中間的0改變一次,   改變從左到右連續的一和中間的0再改變中間的0,一共3次,反過來為6次。

#include<stdio.h>
#define N 1000020
char a[N],b[N];
int c[N];
int main()
{
	long long t,n,i,sum,temp;
	scanf("%lld",&t);
	while(t--)
	{
		sum=0;
		scanf("%lld",&n);
		scanf("%s %s",a,b);
		for(i=0;i<n;i++)
		{
			c[i]=(a[i]-'0')^(b[i]-'0');
			sum+=c[i];
		}
		if(n==1&&c[0]==0)
		{
			printf("1\n");
			continue;
		}
		if(sum==n)
		{
			printf("%lld\n",(n-1)*2);
			continue;
		}
		if(sum==0)
		{
			printf("%lld\n",n*(n+1)/2);
			continue;
		}
		temp=0;
		if(c[0]==1)
			temp++;
		for(i=1;i<n;i++)
		{
			if(c[i]==1&&c[i-1]!=1)
				temp++;
			if(temp>2)
				break;
		}
		if(temp>2)
		{
			printf("0\n");
			continue;
		}
		if(temp==1)
		{
			printf("%lld\n",(n-1)*2);     
		}
		else if(temp==2)
		{
			printf("6\n");
		}
	}
	return 0;
}