标签:while 输入 pre 表示 span code typedef 枚举 clipboard
5
1 8 6 2 5
但是因为最大子序和的时候是不是单调队列做的,所以还是当作再熟悉一下单调队列
思路很清晰,将环断开变成二倍长,枚举每个位置i,求i-n/2<=j<=i-1的区间范围内a[j]-j的最大值maxx
这个就需要单调队列维护一下,然后每个对于每个i最大值就是i+a[i]-(maxx)
最后比较一下即可
我们需要维护一个单调递减的队列,因为对于位置靠前但是值更小的值是没意义的,所以每次进入值时这个值一定要是队列里面的最小值
#include "bits/stdc++.h" using namespace std; const int maxn=2e6+10; typedef long long ll; int a[maxn]; int b[maxn]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); a[i+n]=a[i]; } if(n==1) { printf("0\n"); return 0; } int st=0,en=0,ans=0; for(int i=2;i<=2*n;i++) { int temp=a[i-1]-i+1; if(en==0) { b[en++]=temp; } else { while(en-1>=st) { if(b[en-1]>=temp) { b[en++]=temp; break; } else { en--; } } if(st==en) { b[st]=temp; en++; } } int posi=i-(n/2+1);//超出范围的值要弹出 if(posi>=1&&a[posi]-posi==b[st]) { st++; } ans=max(b[st]+i+a[i],ans); } printf("%d\n",ans); return 0; }
标签:while 输入 pre 表示 span code typedef 枚举 clipboard
原文地址:https://www.cnblogs.com/xiaolaji/p/10803346.html