bzoj1057: [ZJOI2007]棋盘制作

为什么我看了路牌才会做啊QWQ我好菜啊QWQ

对于一个点预处理出符合条件的情况下往后最多能选多少个

为了方便起见我们把偶数行的点全部取反

那么就变成单调栈裸题了

这题数据太水我最后忘清栈都能A-_-!

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;

int mp[2100][2100],L[2][2100][2100];
int top,sta[2100],pos[2100];
int main()
{
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%d",&mp[i][j]);
            if(i%2==0)mp[i][j]^=1;
        }
    memset(L,0,sizeof(L));
    for(int i=1;i<=n;i++)
    {
        L[mp[i][m]][i][m]=1;
        for(int j=m-1;j>=1;j--)
            L[mp[i][j]][i][j]=(mp[i][j]!=mp[i][j+1])*L[mp[i][j+1]][i][j+1]+1;
    }
    
    int mx1=0,mx2=0;
    for(int w=0;w<=1;w++)
    {
        for(int j=1;j<=m;j++)
        {
            top=1,sta[1]=1,pos[1]=1;
            for(int i=2;i<=n;i++)
            {
                while(top!=0&&L[w][i][j]<=L[w][sta[top]][j])
                {
                    int a=L[w][sta[top]][j],b=i-pos[top];
                    if(a>b)swap(a,b);
                    mx1=max(mx1,a*a);
                    mx2=max(mx2,a*b);
                    top--;
                }
                sta[++top]=i,pos[top]=sta[top-1]+1;
            }
            while(top!=0)
            {
                int a=L[w][sta[top]][j],b=n-pos[top]+1;
                if(a>b)swap(a,b);
                mx1=max(mx1,a*a);
                mx2=max(mx2,a*b);
                top--;
            }
        }
    }
    printf("%d\n%d\n",mx1,mx2);
    return 0;
}

 

posted @ 2018-10-31 09:15  AKCqhzdy  阅读(...)  评论(... 编辑 收藏