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

CF724G. Xor-matic Number of the Graph

CF1093E [Intersection of Permutations]

CF1093:E. Intersection of Permutations(树状数组套主席树)