…平均数最大我居然不知道要二分答案,似乎是很常见的思路?我好弱。
每次二分一个答案mid,维护ai−mid的前缀和,每次枚举一个i,将
#include<iostream>
#include<cstdio>
#define eps 1e-7
#define N 200005
using namespace std;
long double sum[N];
int a[N];
int n,L,R,mx;
int Q[2][N],l[2],r[2];
long long ans;
inline int read()
{
int a=0,f=1; char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
return a*f;
}
long long gcd(long long a,long long b)
{
return b==0?a:gcd(b,a%b);
}
bool judge(long double y)
{
for (int i=1;i<=n;i++)
sum[i]=sum[i-1]+a[i]-y;
l[0]=l[1]=1;
r[0]=r[1]=0;
for (int i=L;i<=n;i++)
{
int w=i&1,x=i-L;
int *q=Q[w];
while (r[w]>=l[w]&&sum[x]<sum[q[r[w]]]) r[w]--;
while (r[w]>=l[w]&&q[l[w]]<i-R) l[w]++;
q[++r[w]]=x;
if (sum[i]-sum[q[l[w]]]>=0) return ans=i-q[l[w]];
}
return false;
}
int main()
{
n=read(); L=read(); R=read();
if (L&1) L++;
if (R&1) R--;
for (int i=1;i<=n;i++)
{
a[i]=read();
mx=max(a[i],mx);
a[i+n]=a[i];
}
n<<=1;
long double l=0,r=mx;
while (r-l>=eps)
{
long double mid=(l+r)/2;
if (judge(mid)) l=mid;
else r=mid;
}
long double x=(l+r)/2;
long long w=(long long)(ans*x+0.5);
long long d=gcd(w,ans);
w/=d; ans/=d;
if (ans==1) cout << w;
else cout << w << "/" << ans;
return 0;
}