题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6070

题意: 给出一个题目提交序列, 从中选出一个正确率最小的子串. 选中的子串中每个题目当且仅当最后一次提交是正确的.

思路: 分数规划

二分答案, 然后在 check 函数中查找是否存在某个区j间 [l, r] 使得 sum(l, r) / (r - l + 1) <= mid, 即 sum(l, r) + l * mid <= (r + 1) * mid. 可以用个线段树来维护 sum(l, r) + l * mid . 建树时直接将 l * mid 放入树中, 然后从左到右枚举 r, 对于当前 i, a[i] 对区间 [pre[i] + 1, i] 的贡献为一(区间 [1, pre[i]] 内的贡献之前的a[i]已经计算了) . 这样对于当前更新后, 1 <= j <= i , sum[j] 即为区间 [j, i] 内的贡献. 那么对于当前 i, query(1, i) 就得到了所有以 i 为后缀的区间的贡献最小值. 遍历完 r 后即得到了所有区间的贡献最小值.

最后要注意一下线段树区间更新,区间最值的 lazy 数组维护写法, 最值和区间求和是不同的.

代码:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std; const double eps = 1e-;
const int MAXN = 6e4 + ;
int a[MAXN], pre[MAXN], last[MAXN], n;
double sum[MAXN << ], lazy[MAXN << ]; void push_up(int rt){ //向上更新取最值
sum[rt] = min(sum[rt << ], sum[rt << | ]);
} void push_down(int rt){
if(lazy[rt]){//将标记向下更新,维护的是最值,sum不需要求和
lazy[rt << ] += lazy[rt];
lazy[rt << | ] += lazy[rt];
sum[rt << ] += lazy[rt];
sum[rt << | ] += lazy[rt];
lazy[rt] = ;
}
} void build(int l, int r, int rt, double value){
lazy[rt] = ;
if(l == r){
sum[rt] = value * l;
return;
}
int mid = (l + r) >> ;
build(lson, value);
build(rson, value);
push_up(rt);
} void update(int L, int R, int value, int l, int r, int rt){
if(L <= l && R >= r){
lazy[rt] += value;
sum[rt] += value;//维护的是最值,sum不需要求和
return;
}
push_down(rt);
int mid = (l + r) >> ;
if(L <= mid) update(L, R, value, lson);
if(R > mid) update(L, R, value, rson);
push_up(rt);
} double query(int L, int R, int l, int r, int rt){
if(L <= r && R >= r) return sum[rt];
push_down(rt);
double cnt = 1e5;
int mid = (l + r) >> ;
if(L <= mid) cnt = min(cnt, query(L, R, lson));
if(R > mid) cnt = min(cnt, query(L, R, rson));
return cnt;
} bool check(double mid){
build(, n, , mid);
for(int i = ; i <= n; i++){
update(pre[i] + , i, , , n, );
if(query(, i, , n, ) <= (double)mid *(i + )) return true;
}
return false;
} int main(void){
int t;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
memset(pre, , sizeof(pre));
memset(last, , sizeof(last));
for(int i = ; i <= n; i++){
scanf("%d", &a[i]);
pre[i] = last[a[i]];
last[a[i]] = i;
}
double l = , r = ;
while(r - l > eps){
double mid = (l + r) / ;
if(check(mid)) r = mid - eps;
else l = mid + eps;
}
printf("%.5lf\n", r + eps);
}
return ;
}

hdu6070(分数规划/二分+线段树区间更新,区间最值)的更多相关文章

  1. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  2. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

  3. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  4. hdu 1166线段树 单点更新 区间求和

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  5. hdu6070 Dirt Ratio 二分+线段树

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

  6. hdu2795(线段树单点更新&区间最值)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2795 题意:有一个 h * w 的板子,要在上面贴 n 条 1 * x 的广告,在贴第 i 条广告时要 ...

  7. hdu1166(线段树单点更新&区间求和模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1166 题意:中文题诶- 思路:线段树单点更新,区间求和模板 代码: #include <iost ...

  8. 【HDU】1754 I hate it ——线段树 单点更新 区间最值

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

  9. POJ 2892 Tunnel Warfare(线段树单点更新区间合并)

    Tunnel Warfare Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 7876   Accepted: 3259 D ...

随机推荐

  1. python 正则表达式(二)

    下面列举了Python3的所有符号用法,别背,千万别背,用到时来查就行. 字符 含义 . 表示匹配除了换行符外的任何字符注:通过设置 re.DOTALL 标志可以使 . 匹配任何字符(包含换行符) | ...

  2. Saiku_学习_02_Schema Workbench 开发mdx和模式文件

    一.前言 saiku的查询都是通过cube来进行的.因此每当我们要进行一次多维度查询时,都要先修改xml.上传.重启才能生效,不仅效率低,还不利于学习和理解MDX和模式文件. 通过 workbench ...

  3. 一篇 jQuery 常用方法及函数的文章留存备忘。

    jQuery 常见操作实现方式 $("标签名") //取html元素 document.getElementsByTagName("") $("#ID ...

  4. python 标准库 —— http(http.cookiejar)

    1. cookie 信息的读取 from urllib import request import http from http import cookiejar cookie = cookiejar ...

  5. 说几个JS优化技巧吧

    JavaScript一种直译式脚本语言,是一种动态类型.弱类型.基于原型的语言,内置支持类型.它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标 ...

  6. myod中遇到的问题

    一.准备工作 首先在编程之前遇到的第一个问题就是要了解需要编出一个怎样的代码,了解od -tx -tc的具体意思,并观察其输出结果. -tc代表着输出ASCII字符,而-tx则是代表着输出ASCII字 ...

  7. 通过Jquery异步获取股票实时数据

    最近朋友让我帮他做个异步获取数据的程序,暂时服务器什么都没有,所以我就想先拿股票数据打个框架,方便后续开发和移植等事情 代码如下: <!-- 说明:股票看盘 作者:黑桃A 时间:2014-04- ...

  8. oracle rac搭建

    (一)环境准备 主机操作系统 windows10 虚拟机平台 vmware workstation 12 虚拟机操作系统 redhat 5.5 x86(32位) :Linux.5.5.for.x86. ...

  9. 最长递增子序列(LIS)

    最长递增子序列(Longest Increasing Subsequence) ,我们简记为 LIS. 题:求一个一维数组arr[i]中的最长递增子序列的长度,如在序列1,-1,2,-3,4,-5,6 ...

  10. poj 2388 Who's in the Middle(快速排序求中位数)

    一.Description FJ is surveying his herd to find the most average cow. He wants to know how much milk ...