码迷,mamicode.com
首页 > 其他好文 > 详细

【Luogu】P1169棋盘制作(单调栈)

时间:2018-01-19 11:40:07      阅读:103      评论:0      收藏:0      [点我收藏+]

标签:pac   blog   mem   int   algorithm   for   size   read   printf   

  题目链接

  唉……这种题放在NOIP以前我是会做的……但是为什么现在反而不会了……

  单调栈。预处理每个点向上能扩展的最大距离,左右用两遍单调栈扫一遍。注意边界。

  

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cctype>
using namespace std;

inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch==-)    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-0;
        ch=getchar();
    }
    return num*f;
}

int q[2010][2010];
int d[2010][2010][2];
int w[2020];int s[2020];
int stack[2020],top;
int ans;
int cnt;

int main(){
    int n=read(),m=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=m;++j){
            q[i][j]=read()^((i+j+1)%2);
            int now=q[i][j];
            d[i][j][now]=q[i-1][j]==now?d[i-1][j][now]+1:1;
        }
    for(int i=1;i<=n;++i){
        memset(w,0,sizeof(w));    top=0;
        for(int j=1;j<=m;++j){
            w[j]=j;
            while(top&&d[i][stack[top]][0]>d[i][j][0])    w[stack[top--]]=j-1;
            stack[++top]=j;
        }
        //while(top)    w[stack[top--]]=n;
        memset(s,0,sizeof(s));    top=0;
        for(int j=m;j>=1;--j){
            s[j]=j;
            while(top&&d[i][stack[top]][0]>d[i][j][0])    s[stack[top--]]=j+1;
            stack[++top]=j;
        }
        //while(top)    s[stack[top--]]=1;
        for(int j=1;j<=m;++j){
            ans=max(ans,(w[j]-s[j]+1)*d[i][j][0]);
            int MIN=min(w[j]-s[j]+1,d[i][j][0]);
            cnt=max(cnt,MIN*MIN);
        }
    }
    for(int i=1;i<=n;++i){
        memset(w,0,sizeof(w));    top=0;
        for(int j=1;j<=m;++j){
            w[j]=j;
            while(top&&d[i][stack[top]][1]>d[i][j][1])    w[stack[top--]]=j-1;
            stack[++top]=j;
        }
        //while(top)    w[stack[top--]]=n;
        memset(s,0,sizeof(s));    top=0;
        for(int j=m;j>=1;--j){
            s[j]=j;
            while(top&&d[i][stack[top]][0]>d[i][j][1])    s[stack[top--]]=j+1;
            stack[++top]=j;
        }
        //while(top)    s[stack[top--]]=1;
        for(int j=1;j<=m;++j){
            ans=max(ans,(w[j]-s[j]+1)*d[i][j][1]);
            int MIN=min(w[j]-s[j]+1,d[i][j][1]);
            cnt=max(cnt,MIN*MIN);
        }
    }
    printf("%d\n%d",cnt,ans);
    return 0;
}

 

【Luogu】P1169棋盘制作(单调栈)

标签:pac   blog   mem   int   algorithm   for   size   read   printf   

原文地址:https://www.cnblogs.com/cellular-automaton/p/8315186.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!