P5133 题解
P5133 tb148的客人
题目传送门
题解
唯一的一篇题解还是交错题的……
很简单的一个二分加差分题。
显然是二分答案,考虑检验。如果
事实上,还有一种用 set 的做法,大致就是递推出每一种结局的最优方案,但是代码实现起来细节会很多,此处略。
代码:
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int s=0,m=0;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-')m=1;ch=getchar();}
while( isdigit(ch)) s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
}
int n,a[1000005],b[1000005];
bool check(int mid) {
if(mid*2+1>=n) return 1;
for(int i=1;i<=n+1;i++) b[i]=0;
for(int i=1;i<=n;i++) {
int l=(i-mid-a[i]+1+n*2-1)%n+1,r=(i+mid-a[i]+1+n*2-1)%n+1;
if(l<=r) b[l]++,b[r+1]--;
else b[1]++,b[r+1]--,b[l]++,b[n+1]--;
}
for(int i=1,s=0;i<=n;i++)
if((s+=b[i])==n) return 1;
for(int i=1;i<=n+1;i++) b[i]=0;
for(int i=1;i<=n;i++) {
int l=(i-mid-a[n-i+1]+1+n*2-1)%n+1,r=(i+mid-a[n-i+1]+1+n*2-1)%n+1;
if(l<=r) b[l]++,b[r+1]--;
else b[1]++,b[r+1]--,b[l]++,b[n+1]--;
}
for(int i=1,s=0;i<=n;i++)
if((s+=b[i])==n) return 1;
return 0;
}
signed main() {
cin>>n;
for(int i=1;i<=n;i++)
a[i]=read();
int l=0,r=n,mid,ans;
while(l<=r) {
mid=(l+r)>>1;
if(check(mid)) r=mid-1,ans=mid;
else l=mid+1;
}
cout<<ans;
return 0;
}