https://codeforces.com/contest/1381/problem/A2
从高到低位考虑,如果b[i]=当前的a[i],就可以不用换,否则需要把变换前缀i,还要考虑当前的a[1]符不符合,否则先变换1次1
可以知道我们当前的a[1]---a[i]一定在原a[i]序列是连续的,所以我们维护l,r,表示a[1]和a[i]对应的下标,由于区间会翻转,所以维护一个ldir和rdir表示方向,再维护一个cnt表示这段区间翻转了多少次,就能知道当前的a[l]和a[r]是什么数字。
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
typedef long long ll;
const int maxl=3e5+10;
int n,m,cas,k,cnt,tot;
int ans[maxl];
int a[maxl],b[maxl],tmp[maxl];
char s[maxl];
bool in[maxl];
inline void prework()
{
scanf("%d",&n);
scanf("%s",s+1);
for(int i=1;i<=n;i++)
a[i]=s[i]-'0';
scanf("%s",s+1);
for(int i=1;i<=n;i++)
b[i]=s[i]-'0';
}
inline void mainwork()
{
ans[0]=0;
int cnt=0,l=1,ldir=1,r=n,rdir=-1;
for(int i=n;i>=2;i--)
if((a[r]^(cnt&1))!=b[i])
{
if(a[l]^(cnt&1)==b[i])
ans[++ans[0]]=1;
ans[++ans[0]]=i;
++cnt;
swap(l,r);
ldir*=-1;rdir*=-1;
r+=rdir;
}
else
r+=rdir;
if(a[l]^(cnt&1)!=b[1])
ans[++ans[0]]=1;
}
inline void print()
{
printf("%d ",ans[0]);
for(int i=1;i<=ans[0];i++)
printf("%d ",ans[i]);
puts("");
}
int main()
{
int t=1;
scanf("%d",&t);
for(cas=1;cas<=t;cas++)
{
prework();
mainwork();
print();
}
return 0;
}