zoukankan      html  css  js  c++  java
  • ARC081F Flip and Rectangles

    题意简述:给你一个(n*m (n,m<=2000))的0/1矩阵,可以多次将一行或一列所有值xor 1,求最终能得到的最大全1子矩形。

    wdnmd。。看完题毛想法都没有,这就是ARC吗?

    然后orz了yls的blog,发现有一个奇怪的性质,就是对于一个(2*2)的子矩阵,若其1的数量为偶数,那么这个子矩阵可以被转为全1的。

    然后我们考虑在一个合法的子矩阵中,先通过翻转将第一行全部变为1,由于操作不改变(2*2)子矩阵中1数量的奇偶性,那么剩下的行要么全为0,要么全为1,再把全0行翻转一次即可。

    所以我们可以将每个点的值改为以其为左上角的(2*2)的子矩阵的异或值,问题变为了求最大全0子矩阵了。

    使用悬线法/单调栈可做到(O(n^2))

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N=2010;
    int n,m,ans,a[N][N],up[N],L[N],R[N];
    char s[N];
    int main(){
        scanf("%d%d",&n,&m);ans=max(n,m);
        for(int i=1;i<=n;i++){
            scanf("%s",s+1);
            for(int j=1;j<=m;j++)
                a[i][j]=s[j]=='.'?0:1;
        }
        --n;--m;
        for(int i=1;i<=m;i++)L[i]=1,R[i]=m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                a[i][j]^=a[i+1][j]^a[i][j+1]^a[i+1][j+1];
        for(int i=1;i<=n;i++){
            int l=0,r=m+1;
            for(int j=1;j<=m;j++)
                if(a[i][j])up[j]=0,l=j,L[j]=1;
                else ++up[j],L[j]=max(L[j],l+1);
            for(int j=m;j;j--)
                if(a[i][j])r=j,R[j]=m;
                else {
                    R[j]=min(R[j],r-1);
                    ans=max((R[j]-L[j]+2)*(up[j]+1),ans);
                }
        }
        printf("%d
    ",ans);
    }
    
    
  • 相关阅读:
    广佛肇城轨年内通车 佛山西站预计2017年中通车
    MTK+Android编译
    电量检测芯片BQ27510使用心得
    放大电路的分析方法
    放大电路的分析方法
    模拟电子放大电路分析
    模拟电子技术二极管
    unsigned 整型实现无溢出运算
    hdu 5317 RGCDQ(前缀和)
    CodeForces 429 B Working out(递推dp)
  • 原文地址:https://www.cnblogs.com/yxc2003/p/10706720.html
Copyright © 2011-2022 走看看