CF1572B. Xor of 3
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的主要内容,如果未能解决你的问题,请参考以下文章
CF.724G.Xor-matic Number of the Graph(线性基)