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;
    }
    
  • 相关阅读:
    关于ssh的一篇很好的文章
    课后作业--2 阅读计划及问题
    课后作业--1
    课后作业PPT 7
    大道至简 7、8、读后感
    第六章 读后感
    第五篇 读后感
    数组课后作业
    课后作业1:字串加密
    第四篇 读后感
  • 原文地址:https://www.cnblogs.com/AKMer/p/10326737.html
Copyright © 2011-2022 走看看