思路:在某一个位置施法后 这个位置左边的每个位置所需的威力应该为 右边所有怪物都被打掉之后再打自己 右边同理 所以开两个数组 L一个记录在当前位置左边施法后 左边的所有怪物都被打掉之后需要多少威力才能打掉自己 另一个R记录在当前位置右边施法后 右边的所有怪物都被打掉之后需要多少威力才能打掉自己 然后再开两个数组 记录当前位置左边最大的R 和当前位置右边最大的L 即我左边到它位置右边都被打掉之后所需的威力的最大值和右边到它位置左边都被打掉之后所需的威力的最大值 二分答案 二分威力mid 然后在每一个位置查看 是否存在一个位置在释放mid威力之后 左边和右边需要最大威力的那个怪物都能被打掉
#include<bits/stdc++.h>
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;using ll = long long;using PLL = pair<ll,ll>;
const ll MAX = 1e18;const ll MIN = -1e18;const ll INF=0x3f3f3f3f;
const ll Q = 3e5+9;const ll MOD = 1e9 + 7;
ll a[Q],l[Q],r[Q],lcnt[Q],rcnt[Q];ll n;
bool check(ll x){
for (ll i = 1; i <= n; i++)
{
if(rcnt[i-1]<=x and lcnt[i+1]<=x and x>=a[i]) return true;
}
return false;
}
void solve(){
cin>>n;
for (ll i = 1; i <= n; i++)
{
cin>>a[i];
}
for (ll i = 1; i <= n; i++)
{
l[i]=(i-1)+a[i];
}
for (ll i = 1; i <= n; i++)
{
r[i]=(n-i)+a[i];
}
for (ll i = n; i >= 1; i--)
{
lcnt[i]=max(lcnt[i+1],l[i]);
}
for (ll i = 1; i <= n; i++)
{
rcnt[i]=max(rcnt[i-1],r[i]);
}
ll l=1,r=MAX;ll ans=0;
while(l<=r){
ll mid=(l+r)>>1;
if(check(mid)){
r=mid-1;ans=mid;
}else{
l=mid+1;
}
}
cout<<ans;
}
int main(){
ios;ll _=1;//cin>>_;
while (_--)solve();
return 0;
}