题目链接

https://codeforces.com/contest/1344/problem/F

题解

怎么又是神仙数学构造题。。
观察题目中的操作,我们令

\[\textbf{A}_W=\begin{bmatrix}0\\0\end{bmatrix},\ \textbf{A}_R=\begin{bmatrix}1\\0\end{bmatrix},\ \textbf{A}_Y=\begin{bmatrix}0\\1\end{bmatrix},\ \textbf{A}_B=\begin{bmatrix}1\\1\end{bmatrix} \]

则可以发现,mix 操作就相当于把所有的这些向量在 \(\mod 2\) 意义下相加。
考虑交换操作,其实可以等价于左乘 \(2\times 2\) 的矩阵:

\[\textbf{B}_{RY}=\begin{bmatrix}0&1\\1&0\end{bmatrix},\ \textbf{B}_{YB}=\begin{bmatrix}1&1\\0&1\end{bmatrix},\ \textbf{B}_{RB}=\begin{bmatrix}1&0\\1&1\end{bmatrix} \]

于是这就成了一个 \(2n\) 个未知数 \(2m\) 个方程的异或方程组,高斯消元即可。
时间复杂度 \(O(\frac{n^3}{w})\)\(8\) 倍常数。

这种题大概看题解就两分钟的事,但是我这辈子大概都想不出来吧。。。

代码

#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
#define x first
#define y second
#define iter iterator
#define riter reversed_iterator
#define y1 Lorem_ipsum_dolor
using namespace std;

inline int read()
{
	int x = 0,f = 1; char ch = getchar();
	for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
	for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}
	return x*f;
}

const int mxN = 1000;
struct Matrix
{
	int a[2][2];
	Matrix() {memset(a,0,sizeof(a));}
	Matrix operator *(const Matrix &arg) const
	{
		Matrix ret;
		for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) {ret.a[i][j] ^= (a[i][k]&arg.a[k][j]);}
		return ret;
	}
} I,A[4];
Matrix a[mxN+3];
int n,m;

int decode(char x) {return x=='R'?1:(x=='Y'?2:(x=='B'?3:0));}

namespace Gauss
{
	bitset<mxN*2+3> a[mxN*2+3]; int pos[mxN*2+3],sol[mxN*2+3];
	int n,m;
	bool solve()
	{
		for(int i=1,j=1; i<=m&&j<=n; i++,j++)
		{
			while(j<=n)
			{
				bool found = false;
				for(int k=i; k<=m; k++) if(a[k][j])
				{
					swap(a[i],a[k]); found = true;
					break;
				}
				if(found) break;
				j++;
			}
			if(j>n) {break;}
			pos[i] = j;
			for(int k=i+1; k<=m; k++)
			{
				if(a[k][j]) {a[k] ^= a[i];}
			}
		}
		for(int i=m; i>=1; i--) if(pos[i])
		{
			int tmp = a[i][n+1];
			for(int j=pos[i]+1; j<=n; j++)
			{
				tmp ^= (a[i][j]&sol[j]);
			}
			sol[pos[i]] = tmp;
		}
		for(int i=1; i<=m; i++)
		{
			int tmp = a[i][n+1];
			for(int j=pos[i]; j<=n; j++)
			{
				tmp ^= (a[i][j]&sol[j]);
			}
			if(tmp) {return false;}
		}
		return true;
	}
}

int main()
{
	I.a[0][0] = I.a[1][1] = A[3].a[0][1] = A[3].a[1][0] = A[1].a[0][0] = A[1].a[0][1] = A[1].a[1][1] = A[2].a[0][0] = A[2].a[1][0] = A[2].a[1][1] = 1;
	n = read(),m = read();
	for(int i=1; i<=n; i++) a[i] = I;
	Gauss::n = n*2;
	for(int i=1; i<=m; i++)
	{
		char opt[7]; scanf("%s",opt);
		if(opt[0]=='m')
		{
			Gauss::m += 2;
			int cnt = read();
			while(cnt--)
			{
				int x = read();
				Gauss::a[Gauss::m-1][2*x-1] = a[x].a[0][0];
				Gauss::a[Gauss::m-1][2*x] = a[x].a[0][1];
				Gauss::a[Gauss::m][2*x-1] = a[x].a[1][0];
				Gauss::a[Gauss::m][2*x] = a[x].a[1][1];
			}
			scanf("%s",opt); int c = decode(opt[0]);
			Gauss::a[Gauss::m-1][n+n+1] = c&1;
			Gauss::a[Gauss::m][n+n+1] = c>>1;
		}
		else
		{
			int c = decode(opt[0])^decode(opt[1]),cnt = read();
			while(cnt--)
			{
				int x = read(); a[x] = A[c]*a[x];
			}
		}
	}
	if(!Gauss::solve()) {puts("NO");}
	else
	{
		puts("YES");
		for(int i=1; i<=n; i++)
		{
			int x = (Gauss::sol[2*i]<<1)|Gauss::sol[2*i-1];
			printf("%c",x==0?'.':(x==1?'R':(x==2?'Y':'B')));
		}
		puts("");
	}
	return 0;
}