您的位置:首页 > 其它

[悬线法] BZOJ1057 [ZJOI2007]棋盘制作

2016-03-15 11:21 302 查看
当年是怎么把这道悬线法SB题漏掉没刷的

总之悬线法,刚好在省选前复习下

一开始愣是没看出来 诶 太弱

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

inline char nc()
{
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}

inline void read(int &x)
{
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}

inline int sqr(int x){
return x*x;
}

int n,m;
int M[2005][2005];
int left[2005][2005],right[2005][2005],height[2005][2005];

int main()
{
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m);
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
read(M[i][j]);
for (int i=1;i<=n;i++)
{
int l=1,r=1;
while (l<=m)
{
while (r+1<=m && M[i][r]==M[i][r+1]^1) r++;
for (int j=l;j<=r;j++)
left[i][j]=l,right[i][j]=r;
l=r=r+1;
}
}
for (int j=1;j<=m;j++)
left[0][j]=1,right[0][j]=m;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (i==1 || M[i][j]==M[i-1][j]^1)
{
height[i][j]=height[i-1][j]+1;
left[i][j]=max(left[i][j],left[i-1][j]);
right[i][j]=min(right[i][j],right[i-1][j]);
}
else
height[i][j]=1;
int ans1=0,ans2=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
ans1=max(ans1,height[i][j]*(right[i][j]-left[i][j]+1));
ans2=max(ans2,sqr(min(height[i][j],(right[i][j]-left[i][j]+1))));
}
printf("%d\n%d\n",ans2,ans1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: