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\n",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;
}

  

hdu 6070 Dirt Ratio的更多相关文章

  1. HDU 6070 - Dirt Ratio | 2017 Multi-University Training Contest 4

    比赛时会错题意+不知道怎么线段树维护分数- - 思路来自题解 /* HDU 6070 - Dirt Ratio [ 二分,线段树 ] | 2017 Multi-University Training ...

  2. hdu 6070 Dirt Ratio 线段树+二分

    Dirt Ratio Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Spe ...

  3. 2017ACM暑期多校联合训练 - Team 4 1004 HDU 6070 Dirt Ratio (线段树)

    题目链接 Problem Description In ACM/ICPC contest, the ''Dirt Ratio'' of a team is calculated in the foll ...

  4. HDU 6070 Dirt Ratio(线段树)

    Dirt Ratio Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Tot ...

  5. HDU 6070 Dirt Ratio(分数规划+线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意: 找出一个区间,使得(区间内不同数的个数/区间长度)的值最小,并输出该值. 思路: 因为是要求$\f ...

  6. 2017 Multi-University Training Contest - Team 4 hdu6070 Dirt Ratio

    地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6070 题面: Dirt Ratio Time Limit: 18000/9000 MS (Ja ...

  7. hdu6070 Dirt Ratio 二分+线段树

    /** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...

  8. HDU 6070 二分+线段树

    Dirt Ratio Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)Tot ...

  9. 2017 多校4 Dirt Ratio

    多校4 Dirt Ratio(二分+线段树) 题意: 给出n个数,找一段区间使得区间内不同数字个数除以区间长度最小,求这个最小值,\(n<=60000,a_i<=n\) 题解: 二分答案m ...

随机推荐

  1. [转帖]字符编码笔记:ASCII,Unicode 和 UTF-8

    字符编码笔记:ASCII,Unicode 和 UTF-8 http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html 转帖 ...

  2. 使用批处理执行 sql cmd

    当 sql脚本文件太大了, 就可以考虑用这个方式来执行 1.准备好要执行的 sql脚本文件并保存为*.sql格式 2.找到 SQLCMD.EXE 文件所在的路径(每个版本sql路径不一样) C:\Pr ...

  3. Spring Cloud Feign接口返回流

    身无彩凤双飞翼,心有灵犀一点通. 服务提供者 @GetMapping("/{id}") public void queryJobInfoLogDetail(@PathVariabl ...

  4. 虚拟机ubuntu连不上网

    虚拟机ubuntu连不上网 解决地址:https://blog.csdn.net/spy_h/article/details/80933458

  5. JS 装饰器,一篇就够

    更多文章,请在Github blog查看 在 ES6 中增加了对类对象的相关定义和操作(比如 class 和 extends ),这就使得我们在多个不同类之间共享或者扩展一些方法或者行为的时候,变得并 ...

  6. 22-Perl Socket 编程

    1.Perl Socket 编程Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. ...

  7. Java开发自动售货机

    1:先写一个类,包括商品的基本属性 package com.xt.java.base25; public class Goods { private int ID; private String na ...

  8. Spingboot+Mybatis+Oracle项目配置

    配置过程参考: 项目创建:http://how2j.cn/k/springboot/springboot-eclipse/1640.html 集成Mybatis使用Oracle:https://www ...

  9. 利用Cmake 将最新版本OBS编译成windows版本。

    准备工作: 1. VS2013 的最新更新版或者VS2015 2. QT Creater 5.7   https://www.qt.io/ 3.  CMake (cmake-gui) 4. obs 依 ...

  10. 帝国cms 加载更多的实现(父栏目以及子栏目都可以实现)

    1. <div class="pagelist"> <span id="loadmore" class="btn" sty ...