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

题意:

找出一个区间,使得(区间内不同数的个数/区间长度)的值最小,并输出该值。

思路:

因为是要求$\frac{f(x)}{g(x)}$的最值,所以这是分数规划的题目,对于分数规划,是要用二分查找的方式去解决的。

就像官方题解说的,二分查找mid,二分答案mid,检验是否存在一个区间满足$\frac{size(l,r)}{(r-l+1)}<=mid$,表示l~r内不同数的个数。

先把上面的式子转化一下,,用线段树维护区间内不同数的个数,因为l*mid是固定值,所以把它也可以加进去,这样线段树就维护了区间内不等式左边的最小值。

从左到右枚举r,先是在pre[a[r]]+1~r这段区间内将区间值+1,因为这段区间内a[r]并没有出现过。更新完了之后就查询,因为线段树内记录的就是不等式左边的最小值,所以就可以返回最小值然后判断是否小于等于(r+l)*mid。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn=1e6+;
const int mod=;
const double eps=1e-; int n;
double now;
int a[maxn];
int pre[maxn];
double add[maxn<<];
double sum[maxn<<]; void PushUp(int o)
{
sum[o]=min(sum[o<<],sum[o<<|]);
} void PushDown(int o)
{
if(add[o])
{
add[o<<]+=add[o];
add[o<<|]+=add[o];
sum[o<<]+=add[o];
sum[o<<|]+=add[o];
add[o]=;
}
} void build(int l, int r, int o)
{
sum[o]=add[o]=;
if(l==r)
{
sum[o]=l*now;
return ;
}
int mid=(l+r)>>;
build(l,mid,o<<);
build(mid+,r,o<<|);
PushUp(o);
} void update(int ql, int qr, int l, int r, int x, int o)
{
if(ql<=l && qr>=r)
{
sum[o]+=x;
add[o]+=x;
return;
}
PushDown(o);
int mid=(l+r)>>;
if(mid>=ql) update(ql,qr,l,mid,x,o<<);
if(mid<qr) update(ql,qr,mid+,r,x,o<<|);
PushUp(o);
} double query(int ql, int qr, int l, int r, int o)
{
if(ql<=l && qr>=r)
{
return sum[o];
}
PushDown(o);
double ans=INF;
int mid=(l+r)>>;
if(mid>=ql) ans=min(ans,query(ql,qr,l,mid,o<<));
if(mid<qr) ans=min(ans,query(ql,qr,mid+,r,o<<|));
return ans;
} bool check()
{
memset(pre,,sizeof(pre));
build(,n,);
for(int i=;i<=n;i++)
{
double tmp=now*(i+1.0);
update(pre[a[i]]+,i,,n,,);
if(query(,i,,n,)<=tmp) return true;
pre[a[i]]=i;
}
return false;
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]); double l=,r=;
double ans;
while(r-l>=eps)
{
double mid = (r+l)/2.0;
now = mid;
if(check())
{
ans=mid;
r=mid-eps;
}
else l=mid+eps;
}
printf("%.9lf\n",ans);
}
return ;
}

HDU 6070 Dirt Ratio(分数规划+线段树)的更多相关文章

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

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

  2. 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 ...

  3. HDU 6070 Dirt Ratio(线段树)

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

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

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

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

    目录 目录 思路: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 目录 题意:传送门  原题目描述在最下面.  求\(sum/len\)最小值.\(sum\)是一段区间内不同数字的 ...

  6. hdu 6070 Dirt Ratio

    题 OvO http://acm.hdu.edu.cn/showproblem.php?pid=6070 (2017 Multi-University Training Contest - Team ...

  7. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  8. HDU 3074.Multiply game-区间乘法-线段树(单点更新、区间查询),上推标记取模

    Multiply game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  9. HDU 1394 Minimum Inversion Number(线段树求最小逆序数对)

    HDU 1394 Minimum Inversion Number(线段树求最小逆序数对) ACM 题目地址:HDU 1394 Minimum Inversion Number 题意:  给一个序列由 ...

随机推荐

  1. my.cnf 详解

    [client] port =3306 socket =/tmp/mysql.sock [mysqld] port =3306 socket =/tmp/mysql.sock basedir =/us ...

  2. jmeter测试手机号码归属地

    jmeter测试手机号码归属地接口时,HTTP请求有以下两种书写方法: 1.请求和参数一同写在路径中 2.参数单独写在参数列表中 请求方法既可以使用GET方法又可以使用POST方法. 注意:“服务器名 ...

  3. PHPExcel使用-使用PHPExcel导入文件

    导入步骤: 1. 实例化excel读取对象 2. 加载excel文件 ----------------> ( 1>. 全部加载. 2>. 选择加载. ) 3. 读取excel文件 - ...

  4. 启动rabbitmq,提示ERROR: node with name "rabbit" already running on "localhost"

    ➜ ~ rabbitmq-server ERROR: node with name "rabbit" already running on "localhost" ...

  5. MUTABLE和IMMUTABLE集合

    Scala 集合类系统地区分了可变的和不可变的集合.可变集合可以在适当的地方被更新或扩展.这意味着你可以修改,添加,移除一个集合的元素.而不可变集合类,相比之下,永远不会改变.不过,你仍然可以模拟添加 ...

  6. svn 常见问题记录

    One or more files are in a conflicted state 情景:A组员新增文件并提交,B组员更新出现如下图情况. 解决方案:直接拷贝到B组员工作区.

  7. ajax提交form(文本数据以及文件上传)

    $.ajax({ url: 'xxxx.do', type: 'POST', cache: false, data: new FormData($('.layui-form')[0]), proces ...

  8. HDU 4770

    这题说的是一在一个N*M的房间内,然后有些房间不能被灯光照亮,有一个灯可以转动方向,其他的灯只能在固定一个方向上,因为数据比较小,所以比较水,直接暴力的进行枚举就好了,但是还是 wa了很久,原因没认真 ...

  9. Neutron网络学习

    学习 Neutron 系列文章: 转http://www.cnblogs.com/sammyliu/p/4622563.html (1)Neutron 所实现的网络虚拟化 (2)Neutron Ope ...

  10. php 写内容到文件,把日志写到log文件

    php 写内容到文件,把日志写到log文件 <?php header("Content-type: text/html; charset=utf-8"); /******** ...