题意:给定两个长度为n的01序列A和B,要求分别从两个序列中取两段将段中数字取反,使得A和B完全相同,求方案数
n<=1e6,sum(n)<=1e7
思路:现场8Y……
将A和B异或之后问题转化成了在一个01串中取两端,将段中数字取反,使得最终为全0序列,求方案数
找规律之后可得与连续的1的段数有关,设段数为s
s=0时ans=(n+1)*n/2
s=1时ans=2*(n-1)
s=2时ans=6
s>2时ans=0
1 #include<cstdio> 2 #include<cstring> 3 #include<string> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 typedef long long ll; 13 typedef unsigned int uint; 14 typedef unsigned long long ull; 15 typedef pair<int,int> PII; 16 typedef vector<int> VI; 17 #define fi first 18 #define se second 19 #define MP make_pair 20 #define N 1100000 21 #define M 51 22 #define MOD 1000000007 23 #define eps 1e-8 24 #define pi acos(-1) 25 #define oo 1010000000 26 27 char ch[N]; 28 int a[N],b[N],c[N]; 29 30 int main() 31 { 32 //freopen("zoj4060.in","r",stdin); 33 //freopen("zoj4060.out","w",stdout); 34 int cas; 35 scanf("%d",&cas); 36 for(int v=1;v<=cas;v++) 37 { 38 int n; 39 scanf("%d",&n); 40 scanf("%s",ch+1); 41 for(int i=1;i<=n;i++) a[i]=ch[i]-'0'; 42 scanf("%s",ch+1); 43 for(int i=1;i<=n;i++) b[i]=ch[i]-'0'; 44 for(int i=1;i<=n;i++) c[i]=a[i]^b[i]; 45 int s=0; 46 c[0]=c[n+1]=0; 47 for(int i=0;i<=n;i++) 48 if(c[i]==0&&c[i+1]==1) s++; 49 ll ans=0; 50 if(s==0) ans=(ll)(n+1)*n/2; 51 if(s==1) ans=(n-1)*2; 52 if(s==2) ans=6; 53 if(s==3) ans=0; 54 printf("%lld ",ans); 55 } 56 return 0; 57 } 58