zoukankan      html  css  js  c++  java
  • BZOJ1047:[HAOI2007]理想的正方形

    浅谈队列:https://www.cnblogs.com/AKMer/p/10314965.html

    题目传送门:https://lydsy.com/JudgeOnline/problem.php?id=1047

    对于每一行用单调不增和单调不减队列分别维护最小值和最大值。

    对于列,也用单调不增和单调不减队列分别维护最小值和最大值。

    步骤如下:

    (1)、每一行分别把前(n)个数的单调队列建好。

    (2)、取出每一行队头的元素用列的单调队列维护并更新答案。

    (3)、把每一行在([2,n+1])的元素用单调队列维护好,依次类推,直到([b-n+1,b])的答案被统计完。

    时间复杂度:(O(ab))

    空间复杂度:(O(ab))

    代码如下:

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn=1005;
    
    int list1[maxn],list2[maxn];
    int a,b,n,head1,tail1,head2,tail2,ans=2e9;
    
    int read() {
    	int x=0,f=1;char ch=getchar();
    	for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    	for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    	return x*f;
    }
    
    struct Queue_mn {
    	int head,tail;
    	int list[maxn],a[maxn];
    
    	void ins(int id) {
    		while(head!=tail&&a[list[tail-1]]>a[id])tail--;
    		while(head!=tail&&id-list[head]>=n)head++;list[tail++]=id;
    	}
    
    	int front() {
    		return a[list[head]];
    	}
    }Mn[maxn];
    
    struct Queue_mx {
    	int head,tail;
    	int list[maxn],a[maxn];
    
    	void ins(int id) {
    		while(head!=tail&&a[list[tail-1]]<a[id])tail--;
    		while(head!=tail&&id-list[head]>=n)head++;list[tail++]=id;
    	}
    
    	int front() {
    		return a[list[head]];
    	}
    }Mx[maxn];
    
    int main() {
    	a=read(),b=read(),n=read();
    	for(int i=1;i<=a;i++)
    		for(int j=1;j<=b;j++)
    			Mn[i].a[j]=Mx[i].a[j]=read();
    	for(int i=1;i<=a;i++)
    		for(int j=1;j<n;j++)
    			Mn[i].ins(j),Mx[i].ins(j);
    	for(int i=n;i<=b;i++) {
    		for(int j=1;j<=a;j++)
    			Mn[j].ins(i),Mx[j].ins(i);
    		head1=tail1=head2=tail2=0;
    		for(int j=1;j<=a;j++) {
    			int mn=Mn[j].front(),mx=Mx[j].front();
    			while(head1!=tail1&&Mn[list1[tail1-1]].front()>mn)tail1--;
    			while(head1!=tail1&&j-list1[head1]>=n)head1++;list1[tail1++]=j;
    			while(head2!=tail2&&Mx[list2[tail2-1]].front()<mx)tail2--;
    			while(head2!=tail2&&j-list2[head2]>=n)head2++;list2[tail2++]=j;
    			if(j>=n)ans=min(ans,Mx[list2[head2]].front()-Mn[list1[head1]].front());
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Unity The Method Signature Matching Rule
    Unity The Property Matching Rule
    Unity The Type Matching Rule
    Unity The Custom Attribute Matching Rule
    Unity The Member Name Matching Rule
    Unity No Policies
    Unity The Return Type Matching Rule
    Unity The Parameter Type Matching Rule
    Unity The Namespace Matching Rule
    关于TSQL递归查询的(转)
  • 原文地址:https://www.cnblogs.com/AKMer/p/10326737.html
Copyright © 2011-2022 走看看