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

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

      (2017 Multi-University Training Contest - Team 4 - 1004)

      二分答案

      check时,要满足distinct(l,r)/(r-l+1)<val ,将这个不等式转化为distinct(l,r)+val*l<val*(r+1)

      check的时候,从左到右枚举右端点r,用线段树维护查询从1到r中选一个l,distinct(l,r)+val*l的最小值

      lst数组的作用:lst[i]表示枚举右端点时上一个值为i的点出现的位置

      这样的话,线段树的更新就是当枚举到右端点为i的时候,lst[s[i]]+1到i的值全部加1

      查询就是查询1到i中的最小值

      (思路来源 标程之类的东西)

      

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    const int M=6e4+55;
    
    int n;
    int s[M],lst[M];
    double tree[M*3],tag[M*3];
    
    void build(int rt,int li,int ri,double val)
    {
    	tag[rt]=0;
    	if(li==ri)
    	{
    		tree[rt]=val*li;
    		return ;
    	}
    	int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
    	build(lc,li,mid,val);
    	build(rc,mid+1,ri,val);
    	tree[rt]=min(tree[lc],tree[rc]);
    }
    
    void pushdown(int rt,int li,int ri)
    {
    	if(li==ri)
    	{
    		tag[rt]=0;
    		return ;
    	}
    	int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
    	tree[lc]+=tag[rt];
    	tree[rc]+=tag[rt];
    	tag[lc]+=tag[rt];
    	tag[rc]+=tag[rt];
    	tag[rt]=0;
    }
    
    void update(int rt,int li,int ri,int lq,int rq,double val)	//add
    {
    	if(lq<=li && ri<=rq)
    	{
    		tag[rt]+=val;
    		tree[rt]+=val;
    		return ;
    	}
    	int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
    	if(tag[rt])
    		pushdown(rt,li,ri);
    	if(mid>=lq)
    		update(lc,li,mid,lq,rq,val);
    	if(mid+1<=rq)
    		update(rc,mid+1,ri,lq,rq,val);
    	tree[rt]=min(tree[lc],tree[rc]);
    }
    
    double query(int rt,int li,int ri,int lq,int rq)	//get min
    {
    	double ret=1e9+7;
    	if(lq<=li && ri<=rq)
    		return tree[rt];
    	int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
    	if(tag[rt])
    		pushdown(rt,li,ri);
    	if(mid>=lq)
    		ret=min(ret,query(lc,li,mid,lq,rq));
    	if(mid+1<=rq)
    		ret=min(ret,query(rc,mid+1,ri,lq,rq));
    	return ret;
    }
    
    bool check(double val)
    {
    	int i,j;
    	double tmp;
    	build(1,1,n,val);
    	memset(lst,0,sizeof(lst));
    	for(i=1;i<=n;i++)
    	{
    		update(1,1,n,lst[s[i]]+1,i,1);
    		tmp=query(1,1,n,1,i);	//tmp=distinct(l,r)+val*l  
    		if(tmp<val*(i+1))	//distinct(l,r)+val*l<val*(r+1) => distinct(l,r)/(r-l+1)<val 
    			return true;
    		lst[s[i]]=i;
    	}
    	return false;
    }
    
    void solve()
    {
    	double li=0,ri=1,mid;
    	int i,j,cnt=20;
    	while(cnt--)
    	{
    		mid=(li+ri)/2;
    		if(check(mid))
    			ri=mid;
    		else
    			li=mid;
    	}
    	printf("%.10lf
    ",ri);
    }
    
    int main()
    {
    	int i,j;
    	int cas;
    	cin>>cas;
    	while(cas--)
    	{
    		scanf("%d",&n);
    		for(i=1;i<=n;i++)
    			scanf("%d",&s[i]);
    		solve();
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    git分支
    git使用
    多人协作
    python初心记录二
    python初心记录一
    Javascript 概念类知识
    想成为前端工程师?希望读完这篇文章能对你有所帮助。
    Egret note
    cocos2d-js 连连看
    PS置入图片之后保留选区方便C图
  • 原文地址:https://www.cnblogs.com/FxxL/p/7282742.html
Copyright © 2011-2022 走看看