AGC051C

一个无限大的网格,有些点染成了黑色。每次可以把一个2*3的矩形反色。

可以操作任意多次,求最后保留的黑点最少是多少。

(nle 10^5)


考虑什么样的状态可以到达。

不变量:

  1. 每列的异或和,记为(p_i)
  2. 每行中,列模(3)分组的异或和记为(q_{i,k},k=0,1,2)(q_i)要么相等,要么全部相反。

接下来证明其充分性:

如果状态(A)能到(B),由于转移是双向的,所以如果(A,B)能转移到同一个状态,那么可以互相到达。

先强行把所有的(xge 2,yge 3)的黑点全部染白。现在平面分成了四个部分,对这四个部分分别分析,发现确实等价。

(t_k=sum_{i}p_{3i+k},s_k=sum_iq_{i,k})。显然必须满足(t_kequiv s_kpmod 2)

你需要安排(q_i),得到(s_k)(t_k)是给定的。则贡献为(sum_{k}max(s_k,t_k))(此时可以视作一个矩阵,有些列的异或和为(1),有些行的异或和为(1),并且两者个数之差为偶数。把这些行列交成的子矩阵拉出来,成为一个长方形,把长方形分割出一个正方形放对角线,剩下的部分全部放一排)。

问题相当于:你有一些向量((0,0,0),(1,0,0),(0,1,0),(0,0,1)),可以把一些向量取反。把这些向量求和得到(s),最大化(sum_kmax(s_k,t_k))

枚举每个向量取反个数的奇偶性。然后对于(s_k-t_k)最大的,尝试把偶数个向量(k)取反使其变小。


using namespace std;
#include <bits/stdc++.h>
#define N 100005
int n;
map<int,int> p,q;
int t[3];
int c[4];
int id(int x){
	if (!(x==0 || x==1 || x==2 || x==4))
		x^=7;
	if (x==0) return 3;
	if (x==1) return 0;
	if (x==2) return 1;
	if (x==4) return 2;
}
int s[3];
int main(){
	freopen("in.txt","r",stdin);
	scanf("%d",&n);
	for (int i=1;i<=n;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		p[y]^=1;
		q[x]^=1<<y%3;
	}
	for (auto it=p.begin();it!=p.end();++it)
		t[it->first%3]+=it->second;
	for (auto it=q.begin();it!=q.end();++it)
		c[id(it->second)]++;
	int ans=INT_MAX;
	int r[4];
	for (r[0]=0;r[0]<=1 && r[0]<=c[0];++r[0])
		for (r[1]=0;r[1]<=1 && r[1]<=c[1];++r[1])
			for (r[2]=0;r[2]<=1 && r[2]<=c[2];++r[2])
				for (r[3]=0;r[3]<=1 && r[3]<=c[3];++r[3]){
					s[0]=(c[0]-r[0])+r[1]+r[2]+r[3];
					s[1]=r[0]+(c[1]-r[1])+r[2]+r[3];
					s[2]=r[0]+r[1]+(c[2]-r[2])+r[3];
					if (((s[0]^t[0])|(s[1]^t[1])|(s[2]^t[2]))&1)
						continue;
					int fir=0,sec=-1;
					for (int j=1;j<=2;++j)
						if (s[j]-t[j]>s[fir]-t[fir])
							sec=fir,fir=j;
						else if (sec==-1 && s[j]-t[j]>s[sec]-t[sec])
							sec=j;
					if (s[fir]-t[fir]>0 && s[sec]-t[sec]<0){
						int d=min(c[fir]-r[fir],min(s[fir]-t[fir],-(s[sec]-t[sec])))/2*2;
						s[fir]-=d;
						s[sec]+=d;
						s[3^fir^sec]+=d;
					}
					ans=min(ans,max(s[0],t[0])+max(s[1],t[1])+max(s[2],t[2]));
				}
	printf("%d
",ans);
	return 0;
}
原文地址:https://www.cnblogs.com/jz-597/p/14512716.html