CF1572B. Xor of 3

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1572B. Xor of 3相关的知识,希望对你有一定的参考价值。

CF1572B. Xor of 3

题意:

给你个01序列,你有一种操作:每次选位置x,然后位置x,x+1,x+2的值变为三者的异或值。
现在要让所有的数都等于0,请输出存在的合法操作序列

题解:

首先如果有奇数个1,显然是无解的
此时我们从第一个1开始考虑,成对考虑消除1(因为这样异或为0),每次消除掉第一对1
如果两个1之间有奇数个0:
比如10001,100000001,这种是可以直接消掉的
就拿100000001来说,假设第一个1的位置为x,那我们可以依次操作x,x+2,x+4,…,(x<长度),此时序列为:111111101,然后操作x+6就得到111111000,然后再倒着执行x+4,x+2…这样就都变成0

如果两个1之间有偶数个0
这样是不能和上面一样直接消除的,可以先全部变成1,然后需要借助外面的0,也就是如果左边或右边有一个0,就可以消除,否则无解
比如1001 -> 1111 假设 原序列是10010, 右边有一个0, 那么现在11110可以消掉

实现起来挺麻烦的

代码:

#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\\n", a, b);
using namespace std;
bool Handsome;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{
    x= 0;
    char c= getchar();
    bool flag= 0;
    while (c < '0' || c > '9')
        flag|= (c == '-'), c= getchar();
    while (c >= '0' && c <= '9')
        x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();
    if (flag)
        x= -x;
    read(Ar...);
}
template <typename T> inline void write(T x)
{
    if (x < 0) {
        x= ~(x - 1);
        putchar('-');
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
void rd_test(bool &Most)
{
#ifdef ONLINE_JUDGE
#else
	printf("%.2lfMB\\n",(&Most-&Handsome)/1024.0/1024.0);
    startTime = clock ();
    freopen("data.in", "r", stdin);
#endif
}
void Time_test()
{
#ifdef ONLINE_JUDGE
#else
    endTime= clock();
    printf("\\nRun Time:%lfs\\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int maxn=2e5+9;
int a[maxn],nex[maxn];
vector<int>ans;
int n; 
bool Most;
int solve(int x){
	if(x>n)return 0;
	if(nex[x]==0)return 1;
	if(a[x]==0||(nex[x]-x-1)%2){//如果当前位置是0,或者中间有奇数个1 
		if(a[x]==0)
			x=nex[x];//找到后面最近1的位置 
		while(x){
			if((nex[x]-x-1)%2){//中间奇数个1,内部直接消 
				int i;
				for(i=x;i+2<nex[x];i+=2)
					ans.push_back(i);
				for(;i>=x;i-=2)
					ans.push_back(i);
			}
			else {//借助左边的0消除 
				for(int i=x;i+2<nex[x];i+=2)
					ans.push_back(i);
				for(int i=x-1;i+2<=nex[x];i+=2)
					ans.push_back(i);
			}
			x=nex[nex[x]];//下下一个1的位置(因为1都是成对处理) 
		}
		return 1; 
	}
	else{
		//因为中间有偶数个1且当前不是0,所以需要判断后面能否出现0 
		if(solve(nex[x]+1)){
			for(int i=x;i<nex[x]-2;i+=2)
				ans.push_back(i);
			for(int i=nex[x]+1;i-2>=x;i-=2)
				ans.push_back(i-2);
			return 1;
		}
		else
			return 0; 
	} 
}
int main()
{
    rd_test(Most);
	int t;
	read(t);
	while(t--){
		read(n);
		for(int i=1;i<=n;i++)read(a[i]);
		int las=0;
		int cnt=0;
		for(int i=n;i>=1;i--){
			nex[i]=las;
			if(a[i])//如果非0,记录位置
			{
				las=i;
				cnt++;
			} 
		}
		if(cnt%2)//如果奇数个1
		{
			printf("NO\\n");
			continue; 
		}
		ans.clear();
		if(solve(1)){
			printf("YES\\n%d\\n", ans.size());
			for(int i=0; i<ans.size(); i++) {
				printf("%d ", ans[i]);
			}
			printf("\\n");
		} else printf("NO\\n");
	}
    //Time_test();
}






以上是关于CF1572B. Xor of 3的主要内容,如果未能解决你的问题,请参考以下文章

CF1572B. Xor of 3

CF1572B. Xor of 3

CF1572B. Xor of 3

CF.724G.Xor-matic Number of the Graph(线性基)

CF724G. Xor-matic Number of the Graph

CF724G Xor-matic Number of the Graph