题目链接
https://codeforces.com/contest/1344/problem/F
题解
怎么又是神仙数学构造题。。
观察题目中的操作,我们令
[ extbf{A}_W=egin{bmatrix}0\0end{bmatrix}, extbf{A}_R=egin{bmatrix}1\0end{bmatrix}, extbf{A}_Y=egin{bmatrix}0\1end{bmatrix}, extbf{A}_B=egin{bmatrix}1\1end{bmatrix}
]
则可以发现,mix 操作就相当于把所有的这些向量在 (mod 2) 意义下相加。
考虑交换操作,其实可以等价于左乘 (2 imes 2) 的矩阵:
[ extbf{B}_{RY}=egin{bmatrix}0&1\1&0end{bmatrix}, extbf{B}_{YB}=egin{bmatrix}1&1\0&1end{bmatrix}, extbf{B}_{RB}=egin{bmatrix}1&0\1&1end{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;
}