zoukankan      html  css  js  c++  java
  • SPOJ JZPLIT

    Problem

    SPOJ

    Solution

    考虑任意一个作为矩阵四个角的位置

    \(r_i \oplus c_j\oplus a_{i,j}\oplus x_{i,j}=0\)

    \(r_i \oplus c_{j+1}\oplus a_{i,j+1}\oplus x_{i,j+1}=0\)

    \(r_{i+1}\oplus c_j\oplus a_{i+1,j}\oplus x_{i+1,j}=0\)

    \(r_{i+1}\oplus c_{j+1}\oplus a_{i+1,j+1}\oplus x_{i+1,j+1}=0\)

    \(a_{i,j}\oplus a_{i,j+1}\oplus a_{i+1,j}\oplus a_{i+1,j+1}\oplus x_{i,j}\oplus x_{i,j+1}\oplus x_{i+1,j}\oplus x_{i+1,j+1}=0\)

    则只需要解出第一行第一列的操作方法就可以表示其他格子的操作方法。

    未知的状态数就减少到\(O(n+m-1)\)。对于所有第一行第一列的格子列方程,即这行这列的所有操作异或后等于当前状态,然后bitset优化即可。

    时间复杂度\(O(\frac {(n+m)^3} {32})\),注意卡常。

    Code

    #pragma GCC optimize("no-stack-protector")
    #pragma GCC optimize("Ofast")
    #pragma GCC optimize(3)
    #include <cstdio>
    #include <bitset>
    using namespace std;
    typedef long long ll;
    template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
    template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
    template <typename Tp> inline void read(Tp &x)
    {
        x=0;int f=0;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=1,ch=getchar();
        while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        if(f) x=-x;
    }
    int n,m,a[1010][1010],b[2010][2010],ans[1010][1010];
    char s[1010];
    bitset<2010> x[2010];
    inline void calc(int i,int j,int id)
    {
    	b[id][1]^=1;b[id][j]^=1;b[id][i+m-1]^=1;
    	b[id][n+m]^=a[1][1]^a[1][j]^a[i][1]^a[i][j];
    }
    void gauss()
    {
    	int k;
    	for(int i=1;i<n+m;i++)
    	{
    		for(k=i;k<n+m;k++)
    		  if(x[k][i]) break;
    		if(k>=n+m) continue;
    		if(k^i) swap(x[i],x[k]);
    		for(int j=1;j<n+m;j++)
    		  if(i^j&&x[j][i])
    		    x[j]^=x[i];
    	}
    }
    int main()
    {
    	read(n);read(m);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",s+1);
    		for(int j=1;j<=m;j++) a[i][j]=(s[j]=='1');
    	}
    	for(int i=1;i<n+m;i++) b[i][i]=1;
    	for(int i=1;i<n+m;i++) b[1][i]=1;
    	b[1][n+m]=a[1][1];
    	//the first eq
    	for(int i=2;i<=m;i++)
    	{
    		b[i][n+m]=a[1][i];
    		for(int j=1;j<=m;j++) b[i][j]=1;
    	}
    	for(int i=2;i<=n;i++)
    	{
    		b[i+m-1][n+m]=a[i][1];b[i+m-1][1]=1;
    		for(int j=m+1;j<n+m;j++) b[i+m-1][j]=1;
    	}
    	for(int i=2;i<=n;i++)
    	  for(int j=2;j<=m;j++)
    	  {
    	  	calc(i,j,j);
    	  	calc(i,j,i+m-1);
    	  }
    	for(int i=1;i<n+m;i++)
    	  for(int j=1;j<=n+m;j++)
    	    if(b[i][j])
    	      x[i].set(j);
    	gauss();
    	for(int i=1;i<=m;i++) ans[1][i]=x[i][n+m];
    	for(int i=2;i<=n;i++) ans[i][1]=x[i+m-1][n+m];
    	for(int i=1;i<=n;i++,putchar('\n'))
    	  for(int j=1;j<=m;j++)
    	  {
    	  	if(i>1&&j>1)
    	  	  ans[i][j]=a[1][1]^a[i][1]^a[1][j]^a[i][j]^ans[1][1]^ans[i][1]^ans[1][j];
    	  	printf("%d",ans[i][j]);
    	  }
    	return 0;
    }
    
  • 相关阅读:
    ETL Pentaho Data Integration (Kettle) 插入/更新 问题 etl
    Value Investment
    sqlserver 2008r2 表分区拆分问题
    HTTP与HTTPS的区别与联系
    别人分享的面经
    饥人谷开放接口(教程)
    java内存泄漏
    单例模式
    Maven项目上有小红叉咋办
    Socket通信1.0
  • 原文地址:https://www.cnblogs.com/totorato/p/10265971.html
Copyright © 2011-2022 走看看