求出前缀和$s[]$,那么区间$[l,r]$的几乎平均数$=\frac{s[r]-s[l-1]}{r-l}$。
若只有一个询问,那么可以维护$(i,s[i-1])$的凸壳,在凸壳上二分点$(i,s[i])$的切线。
对于多个询问,考虑分块,那么只需要暴力处理零碎部分即可。
时间复杂度$O(n\sqrt{m}\log n)$。
#include<cstdio> #include<algorithm> using namespace std; const int N=100010,M=30010,K=500,inf=2000010; typedef long long ll; int n,m,i,x,f[N],L,R;ll s[N],a[N],b[N]; struct E{int l,r,p;}e[M]; inline bool cmp(const E&a,const E&b){return f[a.l]==f[b.l]?a.r<b.r:f[a.l]<f[b.l];} ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} struct P{ ll u,d; P(){} P(ll _u,ll _d){u=_u,d=_d;} bool operator<(const P&b){return u*b.d<d*b.u;} void reset(){u=-inf,d=1;} void write(){ if(!u)puts("0/1"); else{ ll t=gcd(u>0?u:-u,d); printf("%lld/%lld\n",u/t,d/t); } } }ans[M],best,tmp,now; struct HullA{ int q[N],t; void init(){t=0;} void add(int x){ while(t>1&&(a[q[t]]-a[q[t-1]])*(x-q[t])>=(a[x]-a[q[t]])*(q[t]-q[t-1]))t--; q[++t]=x; } void ask(int x,P&ans){ if(!t)return; int l=2,r=t,o=1,mid; while(l<=r){ mid=(l+r)>>1; if((a[q[mid]]-a[q[mid-1]])*(x-q[mid])<=(b[x]-a[q[mid]])*(q[mid]-q[mid-1]))l=(o=mid)+1;else r=mid-1; } now=P(b[x]-a[q[o]],x-q[o]); if(ans<now)ans=now; } }hA,tA; struct HullB{ int q[N],t; void init(){t=0;} void add(int x){ while(t>1&&(b[q[t]]-b[q[t-1]])*(x-q[t])<=(b[x]-b[q[t]])*(q[t]-q[t-1]))t--; q[++t]=x; } void ask(int x,P&ans){ if(!t)return; int l=1,r=t-1,o=t,mid; while(l<=r){ mid=(l+r)>>1; if((b[q[mid+1]]-b[q[mid]])*(q[mid]-x)<=(b[q[mid]]-a[x])*(q[mid+1]-q[mid]))r=(o=mid)-1;else l=mid+1; } now=P(b[q[o]]-a[x],q[o]-x); if(ans<now)ans=now; } }hB; inline void read(int&a){ char c;bool f=0;a=0; while(!((((c=getchar())>=‘0‘)&&(c<=‘9‘))||(c==‘-‘))); if(c!=‘-‘)a=c-‘0‘;else f=1; while(((c=getchar())>=‘0‘)&&(c<=‘9‘))(a*=10)+=c-‘0‘; if(f)a=-a; } inline void vio(int l,int r){ tA.init(); tmp.reset(); while(l<=r)tA.ask(l,tmp),tA.add(l++); } inline void ask(int l,int r){ while(l<=r)hB.ask(l++,tmp); } int main(){ read(n),read(m); for(i=1;i<=n;i++)read(x),s[i]=s[i-1]+x; for(i=1;i<=n;i++)a[i]=s[i-1],b[i]=s[i]; for(i=1;i<=n;i++)f[i]=min(((i-1)/K+1)*K,n); for(i=1;i<=m;i++){ read(e[i].l),read(e[i].r),e[i].p=i; if(e[i].l+K+5>=e[i].r){ vio(e[i].l,e[i].r); ans[i]=tmp; e[i].l=0; } } sort(e+1,e+m+1,cmp); for(i=1;i<=m;i++)if(e[i].l){ if(f[e[i].l]!=L){ L=f[e[i].l]; R=L-1; hA.init(); hB.init(); best.reset(); } while(R<e[i].r)hB.add(++R),hA.ask(R,best),hA.add(R); vio(e[i].l,L-1); ask(e[i].l,L-1); ans[e[i].p]=best<tmp?tmp:best; } for(i=1;i<=m;i++)ans[i].write(); return 0; }
时间: 2024-10-06 18:34:43