• Codeforces 1344F Piet's Palette (线性代数、高斯消元)


    题目链接

    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;
    }
    
  • 相关阅读:
    7多态与异常处理的课上作业
    软工概论第十五周总结
    构建之法阅读笔记之三
    小组项目冲刺第六天的个人总结
    书店促销
    小组项目冲刺第五天的个人总结
    找水王
    软工概论第十四周总结
    动态规划——买书问题
    小组项目冲刺第四天的个人总结
  • 原文地址:https://www.cnblogs.com/suncongbo/p/12872134.html
Copyright © 2020-2023  润新知