set的insert会超时吗
  • 板块P1565 牛宫
  • 楼主love_a_horse
  • 当前回复4
  • 已保存回复4
  • 发布时间2021/5/5 14:38
  • 上次更新2023/11/4 23:40:43
查看原帖
set的insert会超时吗
279446
love_a_horse楼主2021/5/5 14:38

枚举上下界和右边界,用set记录左边界,set的insert理论上lgn级别的为啥会超时呢

#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
typedef long long LL;
const int N = 1010;

LL sum[N][N];
int mtx[N][N];
int n,m;
set<pair<LL,int>,greater<pair<LL,int>>> S;
LL getsum(int x1,int y1,int x2,int y2)
{
	return sum[x2][y2] + sum[x1-1][y1-1] - sum[x2][y1-1] - sum[x1-1][y2]; 	
} 

int main(void)
{	
	scanf("%d%d",&n,&m);
	memset(sum,0,sizeof sum);
	for(int i = 0;i<n;i++)
	{
		for(int j = 0;j<m;j++)
		{
			scanf("%d",&mtx[i][j]);
		}
	}
	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] + mtx[i-1][j-1];
		}
	}
	//枚举三个边界
	LL ans = -1; 
	for(int i = 1;i<=n;i++)//上边界 
	{
		for(int j = i;j<=n;j++)//下边界
		{
			S.clear();
			S.insert({0,0});
			for(int k = 1;k <= m;k++)//右边界 
			{
				//查找右边界的最大值 sum k >= sum m 的m最小值
				LL sumk = getsum(i,1,j,k);
				//printf("行%d->行%d 列%d->列%d sum = %d\n",i,j,1,k,sumk);
				auto it = S.lower_bound({sumk,0});//第一个小于等于sumk的  
				auto preit = it;
				if(it->second == sumk) ++it;
				if(it != S.end())
				{ 
					//printf("ans更新 (%d,%d,%d,%d) %lld\n",i,j,it->second,k,(LL)(j - i + 1) * (k - it->second));
					ans = max(ans,(LL)(j - i + 1) * (k - it->second));
				}
				auto nxit = S.lower_bound({sumk,0});
				if(nxit != S.end()&&nxit->second <= k) continue;
				while(preit != S.begin() && preit->second >= k)
				{
					it = preit;
					--preit;
					S.erase(it);				
				}	
				if(preit == S.begin() && preit->second >= k) S.erase(preit);
				S.insert({sumk,k});							
			}	
		} 
	}
	printf("%lld",ans);
	return 0;
} 
2021/5/5 14:38
加载中...