rt,一个奇怪的分数(不如我同学的暴力+性质)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll MAXN=1e5+15;
struct node{
ll l,r;
};
ll t,n,l,r,lena,lenb,rcnt,lx,ly,rx,ry,lux,luy,rux,ruy,ans;
//pos:每个位置是哪个区间
//cnt[0]/cnt[1]:0/1出险次数的前缀和
//reg:每个区间的左右端点
ll posa[MAXN],posb[MAXN],cnta[MAXN][2],cntb[MAXN][2];
node rega[MAXN],regb[MAXN];
string a,b,x,y;
int main(){
cin>>t;
while(t--){
cin>>n>>a>>b>>x>>y;
a=' '+a,b=' '+b,x=' '+x,y=' '+y;
memset(cnta,0,sizeof(cnta));
memset(cntb,0,sizeof(cntb));
posa[1]=rcnt=1;
cnta[1][0]=a[1]^'1';
cnta[1][1]=a[1]^'0';
for(ll i=2;i<=n;i++){
if(x[i]^x[i-1]) posa[i]=++rcnt;
else posa[i]=rcnt;
cnta[i][0]=cnta[i-1][0]+(a[i]^'1');
cnta[i][1]=cnta[i-1][1]+(a[i]^'0');
}
posb[1]=rcnt=1;
cntb[1][0]=b[1]^'1';
cntb[1][1]=b[1]^'0';
for(ll i=2;i<=n;i++){
if(y[i]^y[i-1]) posb[i]=++rcnt;
else posb[i]=rcnt;
cntb[i][0]=cntb[i-1][0]+(b[i]^'1');
cntb[i][1]=cntb[i-1][1]+(b[i]^'0');
}
for(ll i=1;i<=n;i++) rega[i]=regb[i]={MAXN,-MAXN};
for(ll i=1;i<=n;i++){
rega[posa[i]]={min(i,rega[posa[i]].l),max(i,rega[posa[i]].r)};
regb[posb[i]]={min(i,regb[posb[i]].l),max(i,regb[posb[i]].r)};
}
l=r=1;
lena=posa[n],lenb=posb[n];
// for(ll i=1;i<=lena;i++) cout<<rega[i].l<<' '<<rega[i].r<<' '<<regb[i].l<<' '<<regb[i].r<<endl;
// cout<<"6 6\n";
lux=luy=rux=ruy=ans=0;
while(l<=lena&&r<=lenb){
lx=cnta[rega[l].r][0]-cnta[rega[l].l-1][0];
ly=cnta[rega[l].r][1]-cnta[rega[l].l-1][1];
rx=cntb[regb[r].r][0]-cntb[regb[r].l-1][0];
ry=cntb[regb[r].r][1]-cntb[regb[r].l-1][1];
lx-=lux,rx-=rux,ly-=luy,ry-=ruy;
//cout<<lx<<' '<<ly<<' '<<rx<<' '<<ry<<endl;
ans+=min(lx,rx)+min(ly,ry);
lux+=min(lx,rx);
rux+=min(lx,rx);
luy+=min(ly,ry);
ruy+=min(ly,ry);
if(rega[l].r<regb[r].r){
l++;
lux=luy=0;
}
else if(rega[l].r>regb[r].r){
r++;
rux=ruy=0;
}
else{
l++,r++;
lux=luy=rux=ruy=0;
}
}
cout<<ans<<endl;
}
return 0;
}