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

    队友已经写过一个代码了,用数组实现的线段树,自己再写了一个结构体的线段树,嗯,就是这样,线段树风格不一样而已。

    题解:满足的关系:res=size(l--->r) /  (r-l+1) ,求得最小的结果。正面解题,因为不知道res,而这样做的枚举每一个区间会得到n2的复杂度,所以枚举每一个可能的答案,然后再找是否存在可以满足的这样解的区间,如果不存在,那就根据枚举的mid和siza(l--->r) /(r-l+1)的关系更改mid的值。这道题目是满足单调性的,所以可以二分答案去做。

    参考代码:

    #include <stdio.h>
    #include <algorithm>
    #include <math.h>
    #include <string.h>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <iostream>
    #define INF 0x3f3f3f3f
    using namespace std;
    const int maxn=100010;
    struct node
    {
        int l,r;
        double sum,lazy;
        void update(double x)
        {
            sum+=x;
            lazy+=x;
        }
    }tree[maxn*4];
    void push_up(int x)
    {
        tree[x].sum=min(tree[x<<1].sum,tree[x<<1|1].sum);
    }
    void push_down(int x)
    {
        double lazyval=tree[x].lazy;
        if(lazyval>1e-9)
        {
            tree[x<<1].update(lazyval);
            tree[x<<1|1].update(lazyval);
            tree[x].lazy=0;
        }
    }
    void build(int x,int l,int r,double Mid)
    {
        tree[x].l=l,tree[x].r=r;//,tree[x].sum=0;
    
        if(r==l) tree[x].sum=Mid*l;
        else
        {
            int mid=(l+r)>>1;
            build(x<<1,l,mid,Mid);
            build(x<<1|1,mid+1,r,Mid);
            tree[x].lazy=0;
            push_up(x);
        }
    }
    void update(int x,int ql,int qr,double val)
    {
        int L=tree[x].l,R=tree[x].r;
        if(ql<=L&&R<=qr)
            tree[x].update(val);
        else
        {
            push_down(x);
            int mid=(L+R)>>1;
            if(mid>=ql) update(x<<1,ql,qr,val);
            if(qr>mid) update(x<<1|1,ql,qr,val);
            push_up(x);
        }
    }
    double query(int x,int ql,int qr)
    {
        int L=tree[x].l,R=tree[x].r;
        if(ql<=L&&R<=qr)
            return tree[x].sum;
        else
        {
            push_down(x);
            double ans=1e20;
            int mid=(L+R)>>1;
            if(mid>=ql) ans=min(ans,query(x<<1,ql,qr));
            if(qr>mid) ans=min(ans,query(x<<1|1,ql,qr));
            //push_up(x);
            return ans;
        }
    }
    int n,a[maxn],last[maxn];
    int fun(double mid)
    {
        build(1,1,n,mid);
        memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)
        {
            update(1,last[a[i]]+1,i,1);
            last[a[i]]=i;
            //printf("%lf %lf
    ",query(1,1,i),mid*(i+1));
            if(query(1,1,i)<=(double)mid*(i+1))
                return 1;
        }
        return 0;
    }
    int  main()
    {
        //freopen("C:\Users\Administrator\Desktop\a.txt","r",stdin);
        //freopen("C:\Users\Administrator\Desktop\b.txt","w",stdout);
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            double mid=0.0,l=0.0,r=1.0,ans=0.0;
            for(int i=0;i<20;i++)
            {
                mid=(l+r)/2;
                if(fun(mid)) r=mid,ans=mid;
                else l=mid;
            }
            printf("%.10lf
    ",ans);
        }
        return 0;
    }

      

  • 相关阅读:
    DataGrid( 数据表格) 组件[2]
    DataGrid( 数据表格) 组件[1]
    Form( 表单) 组件
    Slider( 滑动条) 组件
    内存管理-常见内存泄露-(5)
    Android 内存管理分析(四)
    Android 之 内存管理-查看内存泄露(三)
    Android 内存管理(二)
    正确认识Android的内存管理机制,合理关闭进程 (一)
    谈谈Runtime类中的freeMemory,totalMemory,maxMemory等几个方法
  • 原文地址:https://www.cnblogs.com/MeowMeowMeow/p/7288411.html
Copyright © 2011-2022 走看看