zoukankan      html  css  js  c++  java
  • HDU 6070 Dirt Ratio

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070

    题意:给出一个数列,定义len为某一区间长度,定义size为区间数字种类数,求所有区间最小的size/len;

    思路:线段树+二分答案

    对于所有区间的l,r而言,所求为size(l,r)/(r-l+1)<=mid(二分到当前的答案),可以化为size(l,r)+mid*l<=(r+1)*mid;

    然后就是线段树的维护,我们对线段树的叶子定义为所在点(即L)到当前枚举的R之间这个区间的size(l,r)+mid*l,线段树

    就维护每个区间最小的size(l,r)+mid*l,就好了;又看得出来对于以上式子当其他值不变只是变mid时,随着mid增加右边比

    左边增加的多(r+1>l),而我们要找最小的mid,所以只要满足以上,那么就找更小的mid来试就好;精度的话到1e-5就可以过了;

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define L l,m,u<<1
    #define R m+1,r,u<<1|1
    typedef long long LL;
    const int N=6e4+10;
    const double esp=1e-5;
    double add[N<<2],Min[N<<2];
    int last[N],a[N],n;
    
    void pushUp(int u)
    {
        Min[u]=min(Min[u<<1],Min[u<<1|1]);
    }
    void pushDown(int u)
    {
        if(add[u])
        {
            add[u<<1]+=add[u];
            add[u<<1|1]+=add[u];
            Min[u<<1]+=add[u];
            Min[u<<1|1]+=add[u];
            add[u]=0;
        }
    }
    void build(int l,int r,int u,double v)
    {
        add[u]=0;
        if(l==r)
        {
           Min[u]=l*v;
           return;
        }
        int m=(l+r)>>1;
        build(L,v);
        build(R,v);
        pushUp(u);
    }
    void update(int l1,int r1,int c,int l,int r,int u)
    {
        if(l1<=l && r<=r1)
        {
            add[u]+=c;
            Min[u]+=c;
            return;
        }
        pushDown(u);
        int m=(r+l)>>1;
        if(l1<=m)
            update(l1,r1,c,L);
        if(m<r1)
            update(l1,r1,c,R);
        pushUp(u);
    }
    double query(int l1,int r1,int l,int r,int u)
    {
        if(l1<=l && r<=r1)
        {
            return Min[u];
        }
        pushDown(u);
        int m=(l+r)>>1;
        double ret=1e5;
        if(l1<=m)
            ret=min(ret,query(l1,r1,L));
        if(m<r1)
            ret=min(ret,query(l1,r1,R));
        return ret;
    }
    
    bool check(double m)
    {
        build(1,n,1,m);
        memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)
        {
            update(last[a[i]]+1,i,1,1,n,1);
            last[a[i]]=i;
            if(query(1,i,1,n,1)<=m*(i+1))return true;
        }
        return false;
    }
    
    int main()
    {
       // freopen("input.txt","r",stdin);
        int T;
        for(scanf("%d",&T);T;T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            double l=0.0,r=1.0,m,ans;
            while(r-l>esp)
            {
               m=(l+r)/2;
               if(check(m))r=(ans=m);
               else        l=m;
            }
            printf("%.9lf
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    【CSS】CSS 页面布局:盒子模型(内容区、边框、内边距、外边距)
    压缩/解压文件
    WebApiClient.JIT
    并行+异步执行操作
    JSON输出时不输出某些属性值
    ASP.NET MVC中Filter过滤器的使用
    使用git克隆github上的项目失败,报错error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054
    C# 实现WebSocket通信
    写日志
    list随机生成数值
  • 原文地址:https://www.cnblogs.com/MeowMeowMeow/p/7286494.html
Copyright © 2011-2022 走看看