zoukankan      html  css  js  c++  java
  • 【二分】【线段树】hdu6070 Dirt Ratio

    size(l,r)表示区间l,r权值的种类数,让你求min{size(l,r)/(r-l+1)}(1<=l<=r<=n)。

    last[r]表示a[r]上一次出现的位置,

    就是二分验证mid的时候,先把线段树的每个位置i置成mid*i,然后再枚举右端点r,对[last[r]+1,r]作区间+1,然后check此时的前缀最小值是否小于等于mid*(r+1)即可。

    据说这个是“01分数规划”?哪位dalao求解释一下……(我 01分数规划 只做过 最优比率生成树……)

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define lson rt<<1,l,m
    #define rson rt<<1|1,m+1,r
    const double EPS = 0.0000001;
    int T;
    int n,a[60010],last[60010],now[60010];
    double minv[60010<<2];
    double delta[60010<<2];
    void pushdown(int rt)
    {
        if(delta[rt])
          {
            delta[rt<<1]+=delta[rt];
            delta[rt<<1|1]+=delta[rt];
            minv[rt<<1]+=delta[rt];
            minv[rt<<1|1]+=delta[rt];
            delta[rt]=0;
          }
    }
    void update(int ql,int qr,double v,int rt,int l,int r)
    {
        if(ql<=l&&r<=qr)
          {
            delta[rt]+=v;
            minv[rt]+=v;
            return;
          }
        pushdown(rt);
        int m=(l+r)>>1;
        if(ql<=m) update(ql,qr,v,lson);
        if(m<qr) update(ql,qr,v,rson);
        minv[rt]=min(minv[rt<<1],minv[rt<<1|1]);
    }
    double query(int ql,int qr,int rt,int l,int r)
    {
        if(ql<=l&&r<=qr)
          return minv[rt];
        pushdown(rt);
        int m=(l+r)>>1;
        double res=2147483647.0;
        if(ql<=m) res=min(res,query(ql,qr,lson));
        if(m<qr) res=min(res,query(ql,qr,rson));
        return res;
    }
    bool check(double ratio){
    	memset(minv,0,sizeof(minv));
    	memset(delta,0,sizeof(delta));
    	for(int i=1;i<=n;++i){
    		update(i,i,ratio*(double)i,1,1,n);
    	}
    	for(int i=1;i<=n;++i){
    		update(last[i]+1,i,1.0,1,1,n);
    		if(query(1,i,1,1,n)-ratio*(double)(i+1)<EPS){
    			return 1;
    		}
    	}
    	return 0;
    }
    int main(){
    	scanf("%d",&T);
    	for(;T;--T){
    		memset(now,0,sizeof(now));
    		scanf("%d",&n);
    		for(int i=1;i<=n;++i){
    			scanf("%d",&a[i]);
    		}
    		for(int i=1;i<=n;++i){
    			last[i]=now[a[i]];
    			now[a[i]]=i;
    		}
    		double l=0.0,r=1.0;
    		while(r-l>EPS){
    			double mid=(l+r)*0.5;
    			if(check(mid)){
    				r=mid;
    			}
    			else{
    				l=mid+EPS;
    			}
    		}
    		printf("%.10lf
    ",l);
    	}
    	return 0;
    }
  • 相关阅读:
    phpMyAdmin cannot login to mysql server
    emulation 与 simulation 的区别
    C++类构造函数中的成员初始化
    KEY IDEA For Topology-based Analysis
    NOTES ON [Efficient and Cost-Effective Hybrid Congestion Control for HPC Interconnection Networks]
    Install Google Chrome On Ubuntu 14.04
    idea 远程debug调试
    癌细胞作用于身体
    应用高cpu高内存占用
    Jackson总结:常用注解、整合spring、自定义JsonSerializer
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7281988.html
Copyright © 2011-2022 走看看