站外简单枚举题求调/求hack
  • 板块学术版
  • 楼主A_Cabbage
  • 当前回复39
  • 已保存回复40
  • 发布时间2023/11/14 20:21
  • 上次更新2023/11/14 21:55:10
查看原帖
站外简单枚举题求调/求hack
381354
A_Cabbage楼主2023/11/14 20:21

题意简述: 求一个01矩形中满足“左上角一正方形区域全为1,其余全为0”的子矩形数。

思路:先枚举出合法的正方形,再从每个正方形扩展合法的矩形。时间复杂度O(n2log⁡n)O(n^2\log{n})。只T了一个点,其它点最慢363ms363ms,请问是否有卡掉我这个做法的hackhack数据?或者还可以如何优化?谢谢qwq

#include<bits/stdc++.h>
#define ll long long
#define gch getchar()
#define _ putchar(' ')
#define __ puts("")
#define st first
#define nd second
using namespace std;
ll rd()
{
	ll f=1,x=0; char c;
	while(!isdigit(c=gch)) if(c==45)f=-1;
	while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=gch;
	return f*x;
}
void wt(ll x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) wt(x/10);
	putchar(x%10+'0');
}
const int N=2005,M=4e6+5;
int n,m,ct1,ct2,sm[N][N];
pair<int,int>t[M]; ll as;
struct square{int x,y,len;}s[M];
bool ck1(int a,int b,int l){return sm[a+l][b+l]-sm[a-1][b+l]-sm[a+l][b-1]+sm[a-1][b-1]==(l+1)*(l+1);}
bool ck2(int a,int b,int c,int d,int ss){return sm[a][b]-sm[a][d-1]-sm[c-1][b]+sm[c-1][d-1]==ss;}
int main()
{
	n=rd(),m=rd();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++) 
		{
			int a=rd(); if(a) t[++ct1]={i,j};
			sm[i][j]=sm[i-1][j]+sm[i][j-1]-sm[i-1][j-1]+a;
		}
	for(int k=1;k<=ct1;k++)
	{
		int i=t[k].st,j=t[k].nd,l=0,r=min(n-i,m-j),mid;
		while(l<r){if(ck1(i,j,mid=l+r>>1))l=mid+1;else r=mid;}
		if(ck1(i,j,l-1)) s[++ct2]={i,j,l-1};
	}
	for(int k=1;k<=ct2;k++)
	{
		int kx=s[k].x,ky=s[k].y,kl=s[k].len,ks=(kl+1)*(kl+1);
		for(int i=kl+1;i<=n-kx;i++)
		{
			int a=kx+i,l=kl+1,r=m-ky+1,mid;
			while(l<r){mid=(l+r)>>1;if(ck2(a,ky+mid,kx,ky,ks))l=mid+1;else r=mid;}
			if(ck2(a,ky+l-1,kx,ky,ks)) as+=l-1-kl; else break;
		}
	}
	wt(as);
	return 0;
}
2023/11/14 20:21
加载中...