bzoj3316: JC loves Mkk

题意

给你一个环
让你找到连续的长度∈【l,r】的序列,哦,还要是偶数
并使他的平均数最大

题解

看到环和序列就肯定是copy一份啦
然后平均数最大,多半是二分。。
然后偶数和奇数。。不会了。。
网上说是对于奇数位和偶数位各开一个单调队列,新姿势Get
然后就完了。。
CODE:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int N=100005*2;
int n,L,R;
int a[N];
int mx;
int q[2][N],l[2],r[2];//两个单调队列 
long long ans;//选了多少个数 
long double sum[N];
bool check (long double x)
{
    for (int u=1;u<=n;u++) sum[u]=sum[u-1]+a[u]-x;
    l[1]=l[0]=1;r[1]=r[0]=0;
    for (int u=L;u<=n;u++)
    {
        int w=u&1;
        int x=u-L;
        while (l[w]<=r[w]&&sum[x]<sum[q[w][r[w]]]) r[w]--;
        while (l[w]<=r[w]&&q[w][l[w]]<u-R) l[w]++;
        q[w][++r[w]]=x;
        if (sum[u]-sum[q[w][l[w]]]>=0)
        {
            ans=(long long)(u-q[w][l[w]]);
            return true;
        }
    }
    return false;
}
long long gcd(long long x,long long y){return x==0?y:gcd(y%x,x);}
int main()
{
    scanf("%d%d%d",&n,&L,&R);
    for (int u=1;u<=n;u++)  
    {
        scanf("%d",&a[u]);
        mx=max(a[u],mx);
    }
    for (int u=1;u<=n;u++) a[u+n]=a[u];
    n*=2;
    if (L%2!=0) L++;if (R%2!=0) R--;
    long double l=0,r=(long double)mx;

    while (r-l>1e-7)
    {
        long double mid=(l+r)/2.0;
        if (check(mid)) l=mid;
        else r=mid;
    }
    long double x=(l+r)/2;   
    long long w=(long long)(ans*x+0.5);
    long long ooo=gcd(w,ans);
    ans/=ooo;w/=ooo;
    if (ans==1) printf("%lld\n",w);
    else printf("%lld/%lld\n",w,ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值