蛤省省选果然水啊,我这种蒟蒻都能一遍A。
横向纵向维护两个单调队列,做两次求最大和最小的,总复杂度$O(NM)$
码农题,考察代码实现能力
//BZOJ 1047 //by Cydiater //2016.9.17 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <map> #include <iomanip> #include <string> #include <algorithm> #include <queue> using namespace std; #define ll long long #define up(i,j,n) for(int i=j;i<=n;i++) #define down(i,j,n) for(int i=j;i>=n;i--) ; const int oo=0x3f3f3f3f; inline int read(){ ,f=; ;ch=getchar();} +ch-';ch=getchar();} return x*f; } int N,M,K,a[MAXN][MAXN],head[MAXN],tail[MAXN],lable_max[MAXN][MAXN],lable_min[MAXN][MAXN],q[MAXN][MAXN],extro_q[MAXN],extro_head,extro_tail,ans=oo; namespace solution{ inline void push(int co,int id){q[co][++tail[co]]=id;} void init(){ N=read();M=read();K=read(); up(i,,N)up(j,,M)a[i][j]=read(); } void Queue_max(){ memset(tail,,sizeof(tail)); up(i,,N)head[i]=; up(i,,N)up(j,,K){ while(head[i]<=tail[i]&&a[i][j]>a[i][q[i][tail[i]]])tail[i]--; push(i,j);//load y } extro_head=;extro_tail=; up(i,,K-){ while(extro_head<=extro_tail&&a[i][q[i][head[i]]]>a[extro_q[extro_tail]][q[extro_q[extro_tail]][head[extro_q[extro_tail]]]])extro_tail--; extro_q[++extro_tail]=i;//load x } up(i,K,N){ >K&&extro_head<=extro_tail)extro_head++; while(extro_head<=extro_tail&&a[i][q[i][head[i]]]>a[extro_q[extro_tail]][q[extro_q[extro_tail]][head[extro_q[extro_tail]]]])extro_tail--; extro_q[++extro_tail]=i;//load x lable_max[i][K]=a[extro_q[extro_head]][q[extro_q[extro_head]][head[extro_q[extro_head]]]]; } up(j,K+,M){ up(i,,N){ >K&&head[i]<=tail[i])head[i]++; while(head[i]<=tail[i]&&a[i][j]>a[i][q[i][tail[i]]])tail[i]--; push(i,j);//load y } extro_head=;extro_tail=; up(i,,K-){ while(extro_head<=extro_tail&&a[i][q[i][head[i]]]>a[extro_q[extro_tail]][q[extro_q[extro_tail]][head[extro_q[extro_tail]]]])extro_tail--; extro_q[++extro_tail]=i;//load x } up(i,K,N){ >K&&extro_head<=extro_tail)extro_head++; while(extro_head<=extro_tail&&a[i][q[i][head[i]]]>a[extro_q[extro_tail]][q[extro_q[extro_tail]][head[extro_q[extro_tail]]]])extro_tail--; extro_q[++extro_tail]=i;//load x lable_max[i][j]=a[extro_q[extro_head]][q[extro_q[extro_head]][head[extro_q[extro_head]]]]; } } } void Queue_min(){ memset(tail,,sizeof(tail)); up(i,,N)head[i]=; up(i,,N)up(j,,K){ while(head[i]<=tail[i]&&a[i][j]<a[i][q[i][tail[i]]])tail[i]--; push(i,j);//load y } extro_head=;extro_tail=; up(i,,K-){ while(extro_head<=extro_tail&&a[i][q[i][head[i]]]<a[extro_q[extro_tail]][q[extro_q[extro_tail]][head[extro_q[extro_tail]]]])extro_tail--; extro_q[++extro_tail]=i;//load x } up(i,K,N){ >K&&extro_head<=extro_tail)extro_head++; while(extro_head<=extro_tail&&a[i][q[i][head[i]]]<a[extro_q[extro_tail]][q[extro_q[extro_tail]][head[extro_q[extro_tail]]]])extro_tail--; extro_q[++extro_tail]=i;//load x lable_min[i][K]=a[extro_q[extro_head]][q[extro_q[extro_head]][head[extro_q[extro_head]]]]; } up(j,K+,M){ up(i,,N){ >K&&head[i]<=tail[i])head[i]++; while(head[i]<=tail[i]&&a[i][j]<a[i][q[i][tail[i]]])tail[i]--; push(i,j);//load y } extro_head=;extro_tail=; up(i,,K-){ while(extro_head<=extro_tail&&a[i][q[i][head[i]]]<a[extro_q[extro_tail]][q[extro_q[extro_tail]][head[extro_q[extro_tail]]]])extro_tail--; extro_q[++extro_tail]=i;//load x } up(i,K,N){ >K&&extro_head<=extro_tail)extro_head++; while(extro_head<=extro_tail&&a[i][q[i][head[i]]]<a[extro_q[extro_tail]][q[extro_q[extro_tail]][head[extro_q[extro_tail]]]])extro_tail--; extro_q[++extro_tail]=i;//load x lable_min[i][j]=a[extro_q[extro_head]][q[extro_q[extro_head]][head[extro_q[extro_head]]]]; } } } void slove(){ Queue_max(); Queue_min(); } void output(){ /*up(i,1,N){ up(j,1,M)cout<<lable_max[i][j]<<' '; cout<<endl; } puts(""); up(i,1,N){ up(j,1,M)cout<<lable_min[i][j]<<' '; cout<<endl; } puts("");*/ up(i,K,N)up(j,K,M)ans=min(ans,lable_max[i][j]-lable_min[i][j]); cout<<ans<<endl; } } int main(){ //freopen("input.in","r",stdin); using namespace solution; init(); slove(); output(); ; }
妈的,下次再也不起这么长的变量名了,敲到手麻