1 条题解

  • 1
    @ 2017-10-24 21:20:08

    二分答案,再用树状数组加二分(只是我不会lowerbound就只能手写一个find函数)维护前缀和。
    #include<bits/stdc++.h>
    const int maxn=100001;
    inline const void read(int &a)
    {
    a=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')
    {
    a=(a<<1)+(a<<3)+c-'0';
    c=getchar();
    }
    }
    inline const void write(int a)
    {
    if(a<0){a=-a;putchar('-');}
    if(a>9)write(a/10);
    putchar('0'+a%10);
    }
    inline const double max(double a,double b)
    {
    if(a>b)return a;
    return b;
    }
    inline const double min(double a,double b)
    {
    if(a<b)return a;
    return b;
    }
    inline const int lowbit(int a)
    {
    return a&(-a);
    }
    int n,k,sum[maxn];
    inline const void modify(int a,int b)
    {
    a=a+1;
    while(a<=n)
    {
    sum[a]+=b;
    a+=lowbit(a);
    }
    }
    inline const int query(int a)
    {
    a=a+1;
    int ans=0;
    while(a)
    {
    ans+=sum[a];
    a-=lowbit(a);
    }
    return ans;
    }
    double hash[maxn],num[maxn],size[maxn],beauty[maxn];
    int order[maxn];
    inline const bool comp(double a,double b)
    {
    if(a<b)return true;
    return false;
    }
    inline const int find(double a)
    {
    int l=1,r=n;
    while(l!=r)
    {
    int mid=(l+r)>>1;
    if(hash[mid]<a)l=mid+1;
    else r=mid;
    }
    while(l-1&&hash[l-1]==a)--l;
    return l;
    }
    inline const int solve(double mid)
    {
    memset(sum,0,sizeof(sum));
    int ans=0;
    num[0]=0;
    for(int i=1;i<=n;i++)num[i]=hash[i]=num[i-1]+size[i]-mid*beauty[i];
    std::sort(hash+1,hash+1+n,comp);
    for(int i=1;i<=n;i++)
    {
    order[i]=find(num[i]);
    ans+=query(order[i]);
    if(num[i]>=0)ans++;
    modify(order[i],1);
    }
    return ans;
    }
    int main()
    {
    double l=100000.0,r=-1.0;
    read(n);read(k);
    int t;
    for(int i=1;i<=n;i++){read(t);size[i]=double(t);}
    for(int i=1;i<=n;i++){read(t);beauty[i]=double(t);r=max(r,size[i]/beauty[i]);l=min(l,size[i]/beauty[i]);}
    while(r-l>=1e-3)
    {
    double mid=(r+l)/2;
    if(solve(mid)>=k)l=mid;
    else r=mid;
    }
    printf("%.2lf",(l+r)/2);
    return 0;
    }

  • 1

信息

难度
9
分类
(无)
标签
(无)
递交数
15
已通过
3
通过率
20%
上传者