bzoj5085 最大 二分+bitset

版权声明:虽然是个蒟蒻但是转载还是要说一声的哟 https://blog.csdn.net/jpwang8/article/details/83414766

Description


给你一个n×m的矩形,要你找一个子矩形,价值为左上角左下角右上角右下角这四个数的最小值,要你最大化矩形
的价值。

第一行两个数n,m,接下来n行每行m个数,用来描述矩形
n, m ≤ 1000

Solution


题目的意思是1*1的矩阵不算子矩阵。。

最小值最大嘛,二分答案嘛。我们把>=mid的位置记为1,<=mid的位置记为0,显然我们要找到一个矩形四个顶点都是1
考虑用bitset,如果两列&起来有不止两个位置为1说明存在。这样做是 n 2 log n 32 \frac{n^2\log n}{32}

当然还有从大到小插入这种套路操作,这样是n2

Code


#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <bitset>
#define rep(i,st,ed) for (int i=st;i<=ed;++i)

const int N=1005;

int rc[N][N],b[N*N],n,m;

std:: bitset <N> bit[N];

bool check(int mid) {
	rep(i,1,n) {
		bit[i]&=0;
		rep(j,1,m) {
			bit[i][j]=rc[i][j]>=mid;
		}
	}
	rep(i,1,n) rep(j,i+1,n) {
		if ((bit[i]&bit[j]).count()>=2) {
			return true;
		}
	}
	return false;
}

int main(void) {
	scanf("%d%d",&n,&m);
	rep(i,1,n) rep(j,1,m) {
		scanf("%d",&rc[i][j]);
		b[++b[0]]=rc[i][j];
	}
	std:: sort(b+1,b+b[0]+1);
	int size=std:: unique(b+1,b+b[0]+1)-b-1;
	rep(i,1,n) rep(j,1,m) {
		rc[i][j]=std:: lower_bound(b+1,b+size+1,rc[i][j])-b;
	}
	int l=1,r=size;
	for (;l<=r;) {
		int mid=(l+r)>>1;
		if (check(mid)) l=mid+1;
		else r=mid-1;
	}
	printf("%d\n", b[l-1]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/jpwang8/article/details/83414766