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. redhat7下对用户账户的管理

    redhat7对用户帐号的管理主要集中在新建,删除和修改三个动作. 1.新建用户 通过useradd --help,我们得到useradd的详细参数. -d 目录 指定用户主目录,如果此目录不存在,则 ...

  2. fish shell 下gopath的设置问题

    GOPATH可以设置多个工程目录,linux下用冒号分隔(必须用冒号,fish shell的空格分割会出错),windows下用分号分隔,但是go get 只会下载pkg到第一个目录,但是编译的时候会 ...

  3. AngularJS 事件广播与接收 $emit $broadcast $on

    AngularJS中的作用域scope有一个非常有层次和嵌套分明的结构. 其中它们都有一个主要的$rootScope(也就说对应的Angular应用或者ng-app),然后其他所有的作用域部分都是继承 ...

  4. logistics回归

    logistic回归的基本思想 logistic回归是一种分类方法,用于两分类问题.其基本思想为: a. 寻找合适的假设函数,即分类函数,用以预测输入数据的判断结果: b. 构造代价函数,即损失函数, ...

  5. jmeter Bean Shell的使用(二)

    BeanShell的用法 在此介绍下BeanShell PreProcessor的用法,其它的beahshell可以类推.在此我们使用beahshell调用自己写的工具类,工具类实现了密码的加.解密功 ...

  6. GridView 点滴

    绑定数据时.在后台给GridView添加事件 protected void grd_RowDataBound(object sender, GridViewRowEventArgs e) { //当前 ...

  7. Summary: sorting Algorithms

    Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item a ...

  8. 剑指offer2

    请实现一个函数,将一个字符串中的字符串空格替换成“%20”.例如:“We Are Happy”转化后为“We%20Are%20Happy” 思路:把字符串转化成字符数组,判断这个字符是不是空格,如果是 ...

  9. cheng gong de daima

    /** * Copyright (c) 2012-2016 ebizwindow, Inc. All rights reserved. * * Permission is hereby granted ...

  10. 你真的了解[super ]关键字吗?

    前言 此篇文章是看了阮老师的es6教程,看到super关键字的时候觉得有必要总结梳理一下,原文还是参考 ECMAScript 6入门. 正文 super 这个关键字,既可以当作函数使用,也可以当作对象 ...