用于处理滑动区间内最大最小值问题
从前向后扫描滑动轨道,每次执行:
- 加入:从队尾开始向前扫描,至当前队尾元素大于/小于待加入元素,从队尾加入当前元素。
- 删除:如果队首元素不在当前区间内,队首出队,至队首在当前区间内。
struct node { ll s,t,v[1000010]; }maxv,minv; bool check(ll x) { minv.t=maxv.t=0; minv.s=maxv.s=1; maxv.v[0]=minv.v[0]=0; for(ll i=1;i<=n;++i) { while(maxv.t>=maxv.s&&w[i].second>w[maxv.v[maxv.t]].second) maxv.t--; maxv.t++; maxv.v[maxv.t]=i; while(maxv.s<=maxv.t&&w[i].first-w[maxv.v[maxv.s]].first>x) maxv.s++; while(minv.t>=minv.s&&w[i].second<w[minv.v[minv.t]].second) minv.t--; minv.t++; minv.v[minv.t]=i; while(minv.t>=minv.s&&w[i].first-w[minv.v[minv.s]].first>x) minv.s++; } }
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; const int N=1000010; int d1[N],l1=1,r1=0; int p1[N]; int d2[N],l2=1,r2=0; int p2[N]; int num[N]; vector<int>a1,a2; int main() { // freopen("1.txt","r",stdin); int n,k;cin>>n>>k; for(int i=1;i<=n;++i) scanf("%d",&num[i]); for(int i=1;i<=n;++i) { while(i-p1[l1]+1>k&&l1<=r1) l1++; while(d1[r1]>num[i]&&l1<=r1) r1--; r1++; d1[r1]=num[i];//最小值 p1[r1]=i; while(i-p2[l2]+1>k&&l2<=r2) l2++; while(d2[r2]<num[i]&&l2<=r2) r2--; r2++; d2[r2]=num[i];//最大值 p2[r2]=i; // if(i>=k) a1.push_back(d1[l1]);a2.push_back(d2[l2]); } for(int i=k-1;i<n;++i) printf("%d ",a1[i]); printf("\n"); for(int i=k-1;i<n;++i) printf("%d ",a2[i]); return 0; }