CF1344F Piet's Palette
Piet's Palette
A sequence of primary colors (red, yellow, blue) is mixed as follows. While there are at least two colors, look at the first two. If they are distinct, replace them with the missing color. If they are the same, remove them from the sequence. In the end, if there is one color, that is the resulting color. Otherwise, if the sequence is empty, we say the resulting color is white. Here are two example mixings:
Piet has a color palette with cells numbered from \(1\) to \(n\). Each cell contains a primary color or is empty. Piet is very secretive, and will not share his palette with you, so you do not know what colors belong to each cell.
However, he did perform \(k\) operations. There are four kinds of operations:
-
In a mix operation, Piet chooses a subset of cells and mixes their colors together in some order. The order is not necessarily by increasing indexes. He records the resulting color. Empty cells are skipped over, having no effect on the mixing process. The mixing does not change the color values stored in the cells.
-
In a RY operation, Piet chooses a subset of cells. Any red cells in this subset become yellow, and any yellow cells in this subset become red. Blue and empty cells remain unchanged.
-
In a RB operation, Piet chooses a subset of cells. Any red cells in this subset become blue, and any blue cells in this subset become red. Yellow and empty cells remain unchanged.
-
In a YB operation, Piet chooses a subset of cells. Any yellow cells in this subset become blue, and any blue cells in this subset become yellow. Red and empty cells remain unchanged.
Piet only tells you the list of operations he performs in chronological order, the indexes involved, and the resulting color of each mix operation. For each mix operation, you also know the order in which the cells are mixed. Given this information, determine the color of each cell in the initial palette. That is, you should find one possible state of the palette (before any operations were performed), or say that the described situation is impossible.
\(1\leq n,k\leq 1000\)。
题解
https://codeforces.com/blog/entry/76819
Equate an empty cell with the color white, and let's represent the colors as \(0/1\) vectors:
Under this representation, mixing becomes addition \(\pmod{2}\). And the operations \(\mathrm{RY}, \mathrm{RB}, \mathrm{YB}\) are linear transformations of the colors. That is, each of these operations is equivalent to multiplying the corresponding matrix by a cell's vector:
We simply have a system of \(2k\) linear equations on \(2n\) unknowns, which we can solve with Gaussian elimination using bitsets.
Complexity is \(O((2k)^2 (2n) / 64)\).
IN int CI(char c){
switch(c){
case 'R': return 1;
case 'Y': return 2;
case 'B': return 3;
default: return 0;
}
}
IN char IC(int c){
switch(c){
case 1: return 'R';
case 2: return 'Y';
case 3: return 'B';
default: return '.';
}
}
CO int N=2e3+10;
int w[2][N];
bitset<N> bas[N];
int ans[N];
int main(){
int n=read<int>();
for(int i=0;i<n;++i) w[0][i]=1,w[1][i]=2; // mark two variables in two equations
function<void(bitset<N>)> insert=[&](bitset<N> val)->void{
for(int i=0;i<n<<1;++i)if(val[i]){
if(bas[i].none()) {bas[i]=val; return;}
val^=bas[i];
}
if(val[n<<1]) puts("NO"),exit(0);
};
for(int k=read<int>();k--;){
char opt[4]; scanf("%s",opt);
if(opt[0]=='m'){
bitset<N> cur[2];
for(int m=read<int>();m--;){
int x=read<int>()-1;
for(int i=0;i<2;++i){
if(w[i][x]&1) cur[i][x<<1]=1;
if(w[i][x]&2) cur[i][x<<1|1]=1;
}
}
char col[2]; scanf("%s",col);
int c=CI(col[0]);
if(c&1) cur[0][n<<1]=1;
if(c&2) cur[1][n<<1]=1;
for(int i=0;i<2;++i) insert(cur[i]);
}
else if(opt[0]=='R' and opt[1]=='Y'){
for(int m=read<int>();m--;){
int x=read<int>()-1;
swap(w[0][x],w[1][x]);
}
}
else if(opt[0]=='R' and opt[1]=='B'){
for(int m=read<int>();m--;){
int x=read<int>()-1;
w[1][x]^=w[0][x];
}
}
else if(opt[0]=='Y' and opt[1]=='B'){
for(int m=read<int>();m--;){
int x=read<int>()-1;
w[0][x]^=w[1][x];
}
}
}
for(int i=(n<<1)-1;i>=0;--i){
ans[i]=bas[i][n<<1];
for(int j=i-1;j>=0;--j)if(bas[j][i]) bas[j]^=bas[i];
}
puts("YES");
for(int i=0;i<n;++i) putchar(IC(ans[i<<1]|ans[i<<1|1]<<1));
return 0;
}