单调队列
n的算法
通过1.弹出队首 2.压入队尾 3.弹出队尾 来保证区间内的单调性
P1886 滑动窗口 /【模板】单调队列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e6+10; 4 struct node 5 { 6 int num,poi; 7 }q[N]; 8 struct nod 9 { 10 int num,poi; 11 }p[N]; 12 int n,k; 13 int a[N]; 14 int main() 15 { 16 cin>>n>>k; 17 for(int i=1;i<=n;++i) 18 cin>>a[i]; 19 int head=1,tail=1; 20 q[head].num=a[1]; 21 q[tail].poi=1; 22 for(int i=1;i<=n;++i) 23 { 24 //cout<<q[head].num<<endl; 25 while(head<=tail&&a[i]<q[tail].num) 26 tail--; 27 tail++; 28 q[tail]=(node){a[i],i}; 29 while(head<=tail&&q[tail].poi-q[head].poi+1>k) 30 head++; 31 if(i>=k) 32 cout<<q[head].num<<" "; 33 } 34 cout<<endl; 35 head=1;tail=1; 36 p[head].num=a[1]; 37 p[head].poi=1; 38 for(int i=1;i<=n;++i) 39 { 40 while(head<=tail&&a[i]>p[tail].num) 41 tail--; 42 tail++; 43 p[tail]=(nod){a[i],i}; 44 while(head<=tail&&p[tail].poi-p[head].poi+1>k) 45 head++; 46 if(i>=k) 47 cout<<p[head].num<<" "; 48 } 49 return 0; 50 }
P2216 [HAOI2007]理想的正方形 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //双重单调队列 2 #include<bits/stdc++.h> 3 using namespace std; 4 namespace _xzy 5 { 6 typedef long long ll; 7 inline int read() 8 { 9 ll sm=0,flag=1; 10 char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')flag=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){sm=sm*10+ch-'0';ch=getchar();} 13 return sm*flag; 14 } 15 ll a,b,n,ans=1e9; 16 ll g[1002][1002]; 17 struct node 18 { 19 ll poi,num; 20 }e[1002],d[1002]; 21 ll maxn[1002][1002],minn[1002][1002]; 22 void work() 23 { 24 for(ll i=1;i<=a;++i) 25 { 26 ll head=1,tail=1,h=1,t=1; 27 e[head]=(node){1,g[i][1]};d[head]=(node){1,g[i][1]}; 28 for(ll j=1;j<=b;++j) 29 { 30 while(head<=tail&&e[tail].num<g[i][j])tail--; 31 tail++;e[tail]=(node){j,g[i][j]}; 32 while(head<=tail&&e[tail].poi-e[head].poi+1>n)head++; 33 34 while(h<=t&&d[t].num>g[i][j])t--; 35 t++;d[t]=(node){j,g[i][j]}; 36 while(h<=t&&d[t].poi-d[h].poi+1>n)h++; 37 38 if(j>=n) 39 { 40 maxn[i][j]=e[head].num;minn[i][j]=d[h].num; 41 } 42 } 43 } 44 for(ll i=n;i<=a;++i) 45 for(ll j=n;j<=b;++j) 46 { 47 ll ma=0,mi=1e9; 48 for(ll k=i;k>=i-n+1;--k) 49 { 50 ma=max(ma,maxn[k][j]);mi=min(mi,minn[k][j]); 51 } 52 ans=min(ans,abs(ma-mi)); 53 } 54 cout<<ans; 55 } 56 void My_main() 57 { 58 a=read();b=read();n=read(); 59 for(ll i=1;i<=a;++i) 60 for(ll j=1;j<=b;++j) 61 g[i][j]=read(); 62 work(); 63 } 64 } 65 int main() 66 { 67 _xzy::My_main(); 68 return 0; 69 }