暴力过了,是兄弟就来卡我
查看原帖
暴力过了,是兄弟就来卡我
79065
A1443356159楼主2021/12/22 09:38
#include<bits/stdc++.h>
using namespace std;
const int N=205;
char S[N][N];
int sum[N][N],n,m;
long long node(int x,int y,int z,int w) {return x*8000000ll+y*40000ll+z*200ll+w;}
int nxt[N*N*N*3],v[N*N*N*3],w[N*N*N*3],head[2097152],sze;
void add(long long x,int val) {
	int u=x&2097151;
	v[++sze]=x;
	w[sze]=val;
	nxt[sze]=head[u];
	head[u]=sze;
}
int qry(long long x) {
	int u=x&2097151;
	for(int i=head[u];i;i=nxt[i])if(v[i]==x)return w[i];
	return 114514;
}
unordered_map<long long,int>F;
int solve(int ux,int uy,int dx,int dy) {
	if(sum[dx][dy]-sum[ux-1][dy]-sum[dx][uy-1]+sum[ux-1][uy-1]==0
	||sum[dx][dy]-sum[ux-1][dy]-sum[dx][uy-1]+sum[ux-1][uy-1]==(dx-ux+1)*(dy-uy+1))return 0;
	int nw=qry(node(ux,uy,dx,dy));
	if(nw!=114514)return nw; 
	if(ux<dx) {
		int l=1,r=dx-ux,mid,L,R;
		while(l<=r) {
			mid=(l+r)>>1;
			L=solve(ux,uy,ux+mid-1,dy);
			if(L+1>=nw)r=mid-1;
			R=solve(ux+mid,uy,dx,dy);
			nw=min(nw,max(L,R)+1);
			if(L==R)break;
			if(L<=R)l=mid+1;
			else r=mid-1;
		}
	}
	if(uy<dy) {
		int l=1,r=dy-uy,mid,L,R;
		while(l<=r) {
			mid=(l+r)>>1;
			L=solve(ux,uy,dx,uy+mid-1);
			if(L+1>=nw)r=mid-1;
			R=solve(ux,uy+mid,dx,dy);
			nw=min(nw,max(L,R)+1);
			if(L==R)break;
			if(L<=R)l=mid+1;
			else r=mid-1;
		}
	}
	add(node(ux,uy,dx,dy),nw);
	return nw; 
}
int main() {
//	freopen("11.txt","r",stdin);
	srand(time(0));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)scanf("%s",S[i]+1);
	for(int i=1;i<=n;++i)
		for(int j=1;j<=m;++j)
			sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+(S[i][j]=='.');
	printf("%d\n",solve(1,1,n,m));
	//printf("%d",size);
	return 0;
}
2021/12/22 09:38
加载中...