重新做了这道题,对单调队列的认识加深了!
枚举一个端点,另一个端点在队首为最优解。
及时扔掉不优解。
每个元素最多入队出队一次。
在优化DP时经常用到。
主要先构造出单调的函数,使得可以枚举一个端点,然后队列维护单调元素。
变成O1找另一个端点。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M = 1e6+7;
int a[M],q[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i],a[i+n]=a[i];
int l=1,r=0;
int mx=0;
for(int i=1;i<=2*n;i++)//枚举右端点i
{
while(l<=r&&i-q[l]>=n/2)l++;
mx=max(mx,i-q[l]+a[i]+a[q[l]]);
while(l<=r&&a[i]-i>=a[q[r]]-q[r])r--;
q[++r]=i;
// cout<<q[r]-q[l]+a[q[r]]+a[q[l]]<<" "<<" = "<<l<<" "<<r<<" - "<<q[l]<< " - "<<q[r]<<endl;
}
cout<<mx<<endl;
return 0;
}