[CF1031E] Triple Flips

\(\text{Problem}:\)Triple Flips

\(\text{Solution}:\)?

考虑初始有一个未确定的大区间 \([1,n]\),每次操作平均减少 \(3\) 的长度(对于区间左端点三个位置的权值进行分类讨论,右侧相同)。当未确定区间 \([l,r]\) 较小时暴搜。暴力打表可以发现,当 \(n\geq 8\) 时必定有解,故最后保留 \(8\)? 个位置进行即可。具体实现可参考代码(毕竟是构造题)。

\(\text{Code}:\)

#include <bits/stdc++.h>
//#pragma GCC optimize(3)
//#define int long long
#define ri register
#define mk make_pair
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define is insert
#define es erase
#define vi vector<int>
#define vpi vector<pair<int,int>>
using namespace std; const int N=100100;
inline int read()
{
	int s=0, w=1; ri char ch=getchar();
	while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘) w=-1; ch=getchar(); }
	while(ch>=‘0‘&&ch<=‘9‘) s=(s<<3)+(s<<1)+(ch^48), ch=getchar();
	return s*w;
}
int n,a[N],len,sta[N],cnt,fir;
struct Node { int x,y,z; };
vector<Node> ans; vi lst;
inline void Opt(int x,int y,int z)
{
	a[x]^=1, a[y]^=1, a[z]^=1;
	ans.eb((Node){x,y,z});
}
void DFS(int x,int now,vi &g)
{
	if(x==cnt+1)
	{
		if(now^fir) return;
		if(lst.empty() || (int)lst.size()>(int)g.size()) lst=g;
		return;
	}
	DFS(x+1,now,g);
	g.eb(sta[x]);
	DFS(x+1,now^sta[x],g);
	g.pop_back();
}
signed main()
{
	n=read();
	for(ri int i=1;i<=n;i++) a[i]=read();
	int l=1,r=n;
	while(r-l+1>8)
	{
		while(r-l+1>8)
		{
			if(!a[l]) l++;
			else if(!a[r]) r--;
			else break;
		}
		if(r-l+1<=8) break;
		if(a[l] && a[l+1] && a[l+2]) Opt(l,l+1,l+2), l+=3;
		else if(a[l] && !a[l+1] && !a[l+2]) Opt(l,l+3,l+6), l+=3;
		else if(a[l] && !a[l+1] && a[l+2]) Opt(l,l+2,l+4), l+=3;
		else if(a[r] && a[r-1] && a[r-2]) Opt(r-2,r-1,r), r-=3;
		else if(a[r] && !a[r-1] && !a[r-2]) Opt(r-6,r-3,r), r-=3;
		else if(a[r] && !a[r-1] && a[r-2]) Opt(r-4,r-2,r), r-=3;
		else if((l+r)&1) Opt(l,(l+r-1)/2,r-1), Opt(l+1,(l+r+1)/2,r), l+=3, r-=3;
		else Opt(l,(l+r)/2,r), Opt(l+1,(l+r)/2,r-1), l+=3, r-=3;
	}
	while(r-l+1<=8 && l>1) l--; while(r-l+1<=8 && r<n) r++;
	len=r-l+1;
	for(ri int i=0;i<len;i++)
	{
		fir|=(a[i+l]<<i);
		for(ri int j=i+2;j<len;j+=2)
		{
			sta[++cnt]=(1<<i)|(1<<((i+j)/2))|(1<<j);
		}
	}
	vi g; DFS(1,0,g);
	if(fir && lst.empty()) return puts("NO")&0;
	puts("YES");
	for(auto i:lst)
	{
		Node w={0,0,0};
		for(ri int j=0;j<len;j++)
		{
			if((i>>j)&1^1) continue;
			if(!w.x) w.x=j+l;
			else if(!w.y) w.y=j+l;
			else if(!w.z) w.z=j+l;
		}
		ans.eb(w);
	}
	if((int)ans.size()>n/3+12) return puts("NO")&0;
	printf("%d\n",(int)ans.size());
	for(auto i:ans) printf("%d %d %d\n",i.x,i.y,i.z);
	return 0;
}

[CF1031E] Triple Flips

上一篇:windows编程一些小知识


下一篇:Dockerfile install miniconda