codeforces1381A2 Prefix Flip (Hard Version)

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;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/107502374