zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    leetcode5 Longest Palindromic Substring
    leetcode17 Letter Combinations of a Phone Number
    leetcode13 Roman to Integer
    leetcode14 Longest Common Prefix
    leetcode20 Valid Parentheses
    leetcode392 Is Subsequence
    leetcode121 Best Time to Buy and Sell Stock
    leetcode198 House Robber
    leetcode746 Min Cost Climbing Stairs
    tomcat下使用druid配置jnid数据源
  • 原文地址:https://www.cnblogs.com/suncongbo/p/12872134.html
Copyright © 2011-2022 走看看