1. 程式人生 > >bzoj5085 最大 二分+bitset

bzoj5085 最大 二分+bitset

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; }