• [Arc081F]Flip and Rectangles


    [Arc081F]Flip and Rectangles

    试题分析

    首先考虑如何操作,发现我们只会选若干行和若干列来进行一次取反。
    这个东西相当于什么呢?相当于交点不变,然后这些行和这些列的其它点取反。
    那么也就是说,当一行的一段和上一行的一段互补或者相等的时候它们是一定能被搞成全黑矩形的。
    然后基于这个结论,我就写了一个(O(n^2log n))的做法,然后完美地被卡了(1.5)的常数?!
    当然,我们还可以继续考虑一下,发现做两遍差分以后这个问题会变得简单,枚举左端点,然后右端点求出最远到哪里(二维差分后当前段最长的0)
    这个用单调栈维护即可,然后对于每一个位置,可以单调栈求出它最左边和最右边最远到哪里,用这个更新答案即可。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    //#include<ctime>
    //#include<cmath>
    //#include<queue>
     
    using namespace std;
    #define LL long long
     
    inline LL read(){
        LL x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    const LL INF = 2147483600;
    const LL MAXN = 100010;
     
    LL H,W;
    char str[MAXN+1];
    LL base[2001],All[2001];
    LL f[2001][2001];
     LL sta[MAXN+1];
    LL L[MAXN+1],R[MAXN+1];
    LL Hei[MAXN+1];
    bool a[2001][2001];
    inline void Get_Da(){
        int top=0; sta[++top]=1;
        for(LL i=2;i<=H;i++) {
            while(top&&Hei[sta[top]]>=Hei[i]) --top;
            L[i]=sta[top]+1; sta[++top]=i;
        } top=0; sta[++top]=H+1;
        for(LL i=H;i>=2;i--) {
            while(top&&Hei[sta[top]]>=Hei[i]) --top;
            R[i]=sta[top]-1; sta[++top]=i;
        } return ;
    }
    vector<int> vec[2001];
    int to[MAXN+1];
     
    int main(){
        //freopen("a.in","r",stdin);
        //freopen("T2s.out","w",stdout);
        H=read(),W=read(); 
        for(LL i=1;i<=W;i++) base[i]=rand(),All[i]=All[i-1]^base[i];//cout<<"base:"<<base[i]<<endl;
        for(LL i=1;i<=H;i++){
            scanf("%s",str+1);
            for(LL j=1;j<=W;j++){
                a[i][j]=(str[j]=='#');
                f[i][j]=a[i][j]^a[i-1][j];
            }
        }  
        for(int i=1;i<=H;i++){
            int top=0;
            for(int j=W;j>=2;j--){
                f[i][j]=f[i][j-1]^f[i][j];
                if(f[i][j]) sta[++top]=j;
            } for(int j=top;j>=1;j--)
                vec[i].push_back(sta[j]);
            vec[i].push_back(W+1);
        } LL ans=max(H,W);
        //cout<<"True:"<<True(2,1,3)<<endl;
        for(LL l=1;l<W;l++){
            //cout<<l<<": ";
            for(LL i=2;i<=H;i++)
                if(l>=vec[i][to[i]]) ++to[i];
            for(LL i=2;i<=H;i++) Hei[i]=vec[i][to[i]]-1-l+1;
            Get_Da();
            for(LL i=2;i<=H;i++)
                ans=max(ans,(R[i]-L[i]+2)*Hei[i]);
        } printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    【Gamma】 Phylab 展示博客
    【技术博客】Postman接口测试教程
    【技术博客】利用Python将markdown文档转为html文档
    【技术博客】使用PhpStorm和Xdebug实现Laravel工程的远程开发及调试
    【技术博客】Laravel5.1文件上传单元测试
    【技术博客】移动端的点击事件与Sticky Hover问题
    【技术博客】 Laravel 5.1单元测试(PHPUnit)入门
    Scrum Meeting博客目录
    团队事后分析
    Gamma阶段测试报告
  • 原文地址:https://www.cnblogs.com/wxjor/p/9682912.html
Copyright © 2020-2023  润新知