题目链接: 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. ES索引瘦身 压缩——_source _all 均disable filed store为no,引入第三方DB存储原始数据,去掉pos倒排和doc_values,强制定期merge segments,将所有fileds合并为一个field big string

    原始数据:835MB ES 设置了_source _all disabled 且设置了仅仅存docs倒排Wed Feb 22 11:58:27 CST 2017Before size:1 /home/ ...

  2. nodejs stream & buffer 互相转换

    stream 转 buffer function streamToBuffer(stream) { return new Promise((resolve, reject) => { let b ...

  3. 8个Javascript小技巧,让你写的代码有腔调

    如果你想确保你的JavaScript在大多数浏览器和移动设备中都可以工作,那么我从大漠等大神指导,原来可以使用f2etest,也可以使用Endtest,browserstack等 1. 使用 + 字符 ...

  4. LOJ2722 「NOI2018」情报中心

    「NOI2018」情报中心 题目描述 C 国和D 国近年来战火纷飞. 最近,C 国成功地渗透进入了D 国的一个城市.这个城市可以抽象成一张有$n$ 个节点,节点之间由$n - 1$ 条双向的边连接的无 ...

  5. 【LeetCode】085. Maximal Rectangle

    题目: Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's ...

  6. pytorch 调用forward 的具体流程

    forward方法的具体流程: 以一个Module为例:1. 调用module的call方法2. module的call里面调用module的forward方法3. forward里面如果碰到Modu ...

  7. Oracle12c多租户如何连接到CDB或PDB、CDB与PDB容器切换

    Oracle 数据库 12 c 多租户选项允许单个容器数据库 (CDB) 来承载多个单独的可插拔数据库 (PDB).那么我们如何连接到容器数据库 (CDB) 和可插拔数据库 (PDB). 1. V$S ...

  8. docker异常处理

    Error running DeleteDevice dm_task_run failed重启docker即可 Error starting daemon: error initializing gr ...

  9. C#调试信息打印到输出窗口

    System.Diagnostics.Debug.WriteLine("aaaa");

  10. 【转】 Pro Android学习笔记(七一):HTTP服务(5):多线程调用HttpClient

    目录(?)[-] 应用共享HttpClient对象的同步问题 创建共享HttpClient代码 创建共享对象 创建可共享的HttpClient对象 使用共享HttpClient对象的代码 基础代码 修 ...