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. JS DOM节点

    html代码: <body onload ="loaded12()"> <form name="form1" action="htt ...

  2. Python中的__init__.py的作用

    当用 import 导入该目录时,会执行 __init__.py 里面的代码 因此在__init__.py文件中,把深层的包的路径缩短,别的地方就可以在引用到目录级别时引到深层的包.

  3. 让人抓狂的MySQL安装-8.0.12版本

    今天一个下午就做了一件事,把MySQL安装成功,安装的过程让人很狂躁.于是一边骂,一边查错,才把这个软件给安装成功了. 详细的安装步骤,这里就不赘述了.参见https://blog.csdn.net/ ...

  4. Py中的多维数组ndarray学习【转载】

    转自:http://blog.sciencenet.cn/home.php?mod=space&uid=3031432&do=blog&id=1064033 1. NumPy中 ...

  5. 机器学习理论基础学习14.1---线性动态系统-卡曼滤波 Kalman filter

    一.背景 动态模型 = 图 + 时间 动态模型有三种:HMM.线性动态系统(kalman filter).particle filter 线性动态系统与HMM的区别是假设相邻隐变量之间满足线性高斯分布 ...

  6. Selenium - Xpath 使用方法

    由于最新版火狐不在支持FireBug等开发工具,可以通过https://ftp.mozilla.org/pub/firefox/releases/下载49版本以下的火狐就可以增加Firebug等扩展了 ...

  7. iOS UI基础-3.0图片浏览器及plist使用

    需求: 1.显示当前图片序号/总图片数 2.显示图片 3.上一张图片.下一张图片转换 4.显示图片描述 下面用代码来实现 // // UYViewController.m // 3.0图片查看器 // ...

  8. 渗透msf工具中andorid被控端的实现

    msf中andoird端的实现代码一共只有8k 核心代码就是下载者. 下载dex,动态执行dex.

  9. 用python与文件进行交互

    一.文件处理 1.介绍 计算机系统:计算机硬件,操作系统,应用程序 应用程序无法直接操作硬件,通过操作系统来操作文件,进而读/写硬件中的文件. python打开文件过程: #打开 f=open('a. ...

  10. php unset()函数销毁变量但没有实现内存释放

    <?PHP $a = "hello";$b = &$a;unset( $b );echo $a; // 输出 helloecho $b; // 报错$b = &quo ...