codeforces #305 B Mike and Feet
跟之前做过的51Nod的移数博弈是一样的QAQ
我们考虑每个数的贡献
定义其左边第一个比他小的数的位置为L
定义其右边第一个比他小的数的位置为R
这个可以用排序+链表 或者 单调队列 搞定
那么对于区间长度1->(R-L-1),该数都可以作为最小值出现
我们在R-L-1上打上标记,最后从后往前来更新答案即可
至此问题得解
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cstdlib> using namespace std; const int maxn=200010; int n; struct Num{ int v,p; }A[maxn],B[maxn]; int nxt[maxn],pre[maxn]; int mx[maxn],ans[maxn]; bool cmp(const Num &A,const Num &B){return A.v>B.v;} void del(int now){ nxt[pre[now]]=nxt[now]; pre[nxt[now]]=pre[now]; } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d",&A[i].v);A[i].p=i; B[i]=A[i]; } sort(B+1,B+n+1,cmp); for(int i=1;i<=n;++i)nxt[i]=i+1,pre[i]=i-1; pre[0]=0;nxt[n+1]=n+1; for(int i=1;i<=n;++i){ int now=B[i].p; int L=pre[now],R=nxt[now]; mx[R-L-1]=max(mx[R-L-1],B[i].v); del(now); } for(int i=n;i>=1;--i)ans[i]=max(ans[i+1],mx[i]); for(int i=1;i<=n;++i)printf("%d ",ans[i]); return 0; }