按着题意直接模拟就好~
先说下思路
8 3
1 3 -1 -3 5 3 6 7
从样例开始,用最小值来说吧..因为最小值比最大值的方法更明显..
我们从第一个开始处理,第一个有没有可能是最小值,当然可能,因为前面不存在嘛~到了第二个数,第二个数有没有可能是最小值,当然也是可能的,因为前面的那个虽然比它小,但是可能会消失嘛..然后到了第三个可能是最小值不?答案也是可以的,而且我已经运行到了第三个,那么前面比它要大的是不是就不可能存在最小值了(假设当前位子为pos,那么比它小的数->pos这段是不是就不可能为最小值了),因为我存在最小值了嘛..
下面是代码(你们把结构体改下,因为它会爆内存...我被坑了):
#include<bits/stdc++.h> #define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0) #define pb push_back #define inf 2000013422 typedef long long ll; const ll mod=1e9+7; const int N=1e6+5; const double eps=1e-7; using namespace std; const int manx=1e7+5; ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);} ll lcm(ll a,ll b) { return a*b/gcd(a,b); } ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a = (a*a)%p;b >>= 1;}return ans%p;} ll Inv(ll x){ return qp(x,mod-2,mod);} ll C(ll n,ll m){if (m>n) return 0;ll ans = 1;for (int i = 1; i <= m; ++i) ans=ans*Inv(i)%mod*(n-i+1)%mod;return ans%mod;} struct node { int v,id; }; node a[N]; node ans1[N]; node ans2[N]; node cnt1[N]; node cnt2[N]; int main() { ios; int n,k; cin>>n>>k; for(int i=1;i<=n;i++) {cin>>a[i].v;a[i].id=i;} int r=1;//操作指针移动 int l1=1,r1=1,g=0;//l1为当前区间的最大值的位子,r1是可选择的最大值的候选位子,g单纯用来记录答案 cnt1[1]=a[1]; while(r<=n) { if(cnt1[l1].id+k<=r) l1++;//先处理边界 while(a[r].v>cnt1[r1-1].v&&r1>l1) r1--;//预先处理到存在比它大的值 cnt1[r1]=a[r]; r1++; if(r>=k) ans1[g++]=cnt1[l1];//记录答案 r++;//处理下个区间 } r=1;//操作指针移动 int l2=1,r2=1;g=0;//l2为当前区间的最小值的位子,r2是可选择的最小值的候选位子,g单纯用来记录答案 cnt2[1]=a[1]; while(r<=n) { if(cnt2[l2].id+k<=r) l2++;//先处理边界 while(a[r].v<cnt2[r2-1].v&&r2>l2) r2--;//预先处理到存在比它小的值 cnt2[r2]=a[r]; r2++; if(r>=k) ans2[g++]=cnt2[l2];//记录答案 r++;//处理下个区间 } for(int i=0;i<n-k+1;i++) cout<<ans2[i].v<<" "; cout<<endl;//输出最小值 for(int i=0;i<n-k+1;i++) cout<<ans1[i].v<<" "; cout<<endl;//输出最大值 return 0; }
不懂的私聊~