BZOJ1047: [HAOI2007]理想的正方形

恩数据水被我卡过去了2333333

我的是n^2logn的。。每一次扫一遍multiset。。

然后居然就真的过去了23333

#include<cstdio>
#include<iostream>
#include<cstring> 
#include<set>
using namespace std;
multiset<int> Sum,Par[1001];

char c;
bool flag;
inline void read(int &a)
{
	flag=false,a=0;
	do c=getchar();while((c<'0'||c>'9')&&c!='-');
	if(c=='-')flag=true,c=getchar();
	while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
	if(flag)a=-a;
}
int MM[1001][1001];
int Min_Par[1001],Max_Par[1001];
int main()
{
	int a,b,n,i,j,k;
	read(a),read(b),read(n);
	for(i=1;i<=a;i++)
	  for(j=1;j<=b;j++)
       read(MM[i][j]);
    for(i=1;i<=a;i++)
	 Par[i].clear();
	for(i=1;i<=n;i++)
	   for(j=1;j<=b;j++)
	     Par[j].insert(MM[i][j]); 
	multiset<int>::iterator tp;
	
	int ans=1000000000;
	for(j=1;j<=b;j++)
	  {
	  	Min_Par[j]=*Par[j].begin();
	  	tp=Par[j].end();
	  	tp--;
		Max_Par[j]=*tp;
	  }
	Sum.clear();
	for(j=1;j<=n;j++)
	  	Sum.insert(Max_Par[j]),Sum.insert(Min_Par[j]);
	tp=Sum.end();
	   	 tp--;
	   	 ans=min(ans,*tp-*Sum.begin());
	for(j=n+1;j<=b;j++)
	   {
	   	 Sum.erase(Sum.find(Max_Par[j-n])),
		 Sum.insert(Min_Par[j]);
	   	 Sum.erase(Sum.find(Min_Par[j-n])),
		 Sum.insert(Max_Par[j]);
	   	 tp=Sum.end();
	   	 tp--;
	   	 ans=min(ans,*tp-*Sum.begin());
	   }
	   
	for(i=2;i<=a-n+1;i++)
	{
	  for(j=1;j<=b;j++)
        	{
			Par[j].erase(Par[j].find(MM[i-1][j]));
			Par[j].insert(MM[i+n-1][j]);
           }
	for(j=1;j<=b;j++)
	  {
	  	Min_Par[j]=*Par[j].begin();
	  	tp=Par[j].end();
	  	tp--;
		Max_Par[j]=*tp;
	  }
	Sum.clear();
	for(j=1;j<=n;j++)
	  	Sum.insert(Max_Par[j]),Sum.insert(Min_Par[j]);
	tp=Sum.end();
	   	 tp--;
	   	 ans=min(ans,*tp-*Sum.begin());
	for(j=n+1;j<=b;j++)
	   {
	   	 Sum.erase(Sum.find(Max_Par[j-n])),Sum.insert(Min_Par[j]);
		 Sum.erase(Sum.find(Min_Par[j-n])),Sum.insert(Max_Par[j]);
	   	 tp=Sum.end();
	   	 tp--;
	   	 ans=min(ans,*tp-*Sum.begin());
	   }
	   
	} 
	printf("%d\n",ans);
} 


你可能感兴趣的:(bzoj)