HDU-6070 Dirt Ratio(二分+线段树+分数规划)
(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
目录
题意:传送门
原题目描述在最下面。
求\(sum/len\)最小值。\(sum\)是一段区间内不同数字的个数,\(len\)是这段区间的长度。
思路:
首先预处理出每个数上一次出现的位置\(pre[i]\)和最后一次出现的位置\(lst[i]\)。这个操作在静态求区间内不同数的个数和动态求区间内不同数的个数都有用到。
法一:
二分答案\(mid\)。枚举序列,每加入一个数就在\(pre[i]-i\)区间加一,因为在以\(i\)为右端点的所有区间内,这么区间多了一个新数字。
对于\(sum/len\leq mid\; \rightarrow sum - len * mid \leq 0\)。我们已经处理了\(sum\),对于\(len*mid\),就在解决每次插入一个数后,在\(1-i\)区间减去\(k\)。最后查询区间最小值,如果小于\(0\)则此\(mid\)符合还可以更小。
因为我们每加入一个数后,查询的是以\(i\)为右端点的区间最小值,所以很自然的就要\(1-i\)每次减去\(k\)。这样才符合上述表达式。感觉画个图更好理解。
法二:
化简表达式为:$sum(L,R)+Lmid \leq Rmid $
\(sum\)的更新和上面一样,但是左边多了一项\(l*mid\)。
怎么办呢?解决方法就是在线段树的每个端点处的值初始化为\(l*mid\)(\(l\)是到\(1\)的距离)。
然后每此更新完后查询区间最小值\(mmin\),如果\(mmin\leq i*mid\)则此\(mid\)符合还可以更小
AC代码:
#include<bits/stdc++.h>
#define lson rt<<1
#define rson rt<<1|1
#define mme(a,b) memset((a),(b),sizeof((a)))
using namespace std;
const int N = 1e5+7;
int n;
int lst[N],pre[N],ar[N];
double sum[N<<2],lazy[N<<2];
void push_up(int rt){
sum[rt]=min(sum[lson],sum[rson]);
}
void push_down(int rt){
if(lazy[rt]){
lazy[lson]+=lazy[rt];
lazy[rson]+=lazy[rt];
sum[lson]+=lazy[rt];
sum[rson]+=lazy[rt];
lazy[rt]=0;
}
}
void update(int L,int R,int l,int r,double c,int rt){
if(L<=l&&r<=R){
sum[rt] += c;
lazy[rt] += c;
return;
}
push_down(rt);
int mid = (l+r)>>1;
if(L<=mid) update(L,R,l,mid,c,lson);
if(R>mid) update(L,R,mid+1,r,c,rson);
push_up(rt);
}
double query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return sum[rt];
}
push_down(rt);
int mid = (l+r)>>1;
double sum=n;
if(L<=mid) sum = min(sum, query(L,R,l,mid,lson));
if(R>mid) sum = min(sum, query(L,R,mid+1,r,rson));
push_up(rt);
return sum;
}
/*
1
5
1 2 1 2 3
sum/len最小值
sum/len <= mid
sum - len*mid <= 0
sum 区间不同数字的个数
len 区间长度
*/
bool ok(double e){
mme(sum,0);mme(lazy,0);
for(int i=1;i<=n;++i){
update(pre[i]+1,i,1,n,1,1);
update(1,i,1,n,-e,1);
if(query(1,i,1,n,1)<=0)return 1;
}
return false;
}
int main(){
int tim;
scanf("%d",&tim);
while(tim--){
scanf("%d",&n);
mme(lst,0);mme(pre,0);
for(int i=1;i<=n;++i){
scanf("%d",&ar[i]);
pre[i]=lst[ar[i]];
lst[ar[i]]=i;
}
double l=0,r=1,mid;
for(int i=0;i<20;++i){
mid=(l+r)/2;
if(ok(mid))r=mid;
else l=mid;
}
printf("%.5f\n", r);
}
return 0;
}
####原题目描述:

HDU-6070 Dirt Ratio(二分+线段树+分数规划)的更多相关文章
- 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 ...
- HDU 6070 Dirt Ratio(线段树)
Dirt Ratio Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Tot ...
- hdu6070 Dirt Ratio 二分+线段树
/** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...
- HDU 6070 - Dirt Ratio | 2017 Multi-University Training Contest 4
比赛时会错题意+不知道怎么线段树维护分数- - 思路来自题解 /* HDU 6070 - Dirt Ratio [ 二分,线段树 ] | 2017 Multi-University Training ...
- K-th occurrence HDU - 6704 (后缀数组+二分线段树+主席树)
大意: 给定串s, q个询问(l,r,k), 求子串s[l,r]的第kk次出现位置. 这是一篇很好的题解: https://blog.csdn.net/sdauguanweihong/article/ ...
- HDU 6070 Dirt Ratio(分数规划+线段树)
http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意: 找出一个区间,使得(区间内不同数的个数/区间长度)的值最小,并输出该值. 思路: 因为是要求$\f ...
- hdu 6070 Dirt Ratio 线段树+二分
Dirt Ratio Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Spe ...
- hdu 6070 Dirt Ratio
题 OvO http://acm.hdu.edu.cn/showproblem.php?pid=6070 (2017 Multi-University Training Contest - Team ...
- [WC2010]重建计划(长链剖分+线段树+分数规划)
看到平均值一眼分数规划,二分答案mid,边权变为w[i]-mid,看是否有长度在[L,R]的正权路径.设f[i][j]表示以i为根向下j步最长路径,用长链剖分可以优化到O(1),查询答案线段树即可,复 ...
随机推荐
- web自动化框架抽取示例【Java+selenium】
web自动化测试框架抽取示例 例子:测试登录模块,对登录的账号和密码进行不同的case校验. 1.1.1 无优化代码login_1 package com.lee.auto.testFrome; im ...
- 高级运维(四):Nginx常见问题处理、安装部署Tomcat服务器、使用Tomcat部署虚拟主机
一.Nginx常见问题处理 目标: 本案例要求对Nginx服务器进行适当优化,以提升服务器的处理性能: 1> 不显示Nginx软件版本号 2> 如果客户端访问服务器提示“Too many ...
- 2018ACM-ICPC EC-Final 现场赛I题 Misunderstanding...Missing 倒着DP
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem: 很多acm群里有题面PDF了,我就不赘述了.简单说一 ...
- python 中的内置高级函数
1.map(function,iterable) map是把迭代对象依次进行函数运算,并返回. 例子: map返回的十分map对象,需要list()函数转化. 2.exec()函数 执行储存在字符串或 ...
- 制作linux根文件系统
转载地址:http://wenku.baidu.com/view/2cb1b4707fd5360cba1adb14.html 2011十一月 24 转 嵌入式根文件系统制作 (3985) (0) 转自 ...
- (14)centos7 进程管理
一.查询进程 1. 进程显示 ps -a 显示当前所有的进程信息 -u 以用户的格式显示进程信息 -x 显示后台进程运行的参数 ps -aux #通常查看内存 USER #执行进程的用户 PID #进 ...
- springboot入门级笔记
springboot亮点:不用配置tomcat springboot不支持jsp 准备:配置jdk 配置maven 访问https://start.spring.io/ 并生成自己的springboo ...
- spring boot开发,jar包一个一个来启动太麻烦了,写一个bat文件一键启动
spring boot开发,jar包一个一个来启动太麻烦了,写一个bat文件一键启动 @echo offcd D:\workProject\bushustart cmd /c "title ...
- CTF杂项思路工具分享————2019/5/30
分享碰到的一些奇奇怪怪的杂项解题方式: 键盘坐标密码: 题目给出一段字符串:11 21 31 18 27 33 34 对照上面的表格,就可以很清晰的看出来密文为:QAZIJCV 猪圈码: 题目为: 一 ...
- java中trim()方法是用来干什么的?
trim()的作用是去掉字符串两端的多余的空格,注意,是两端的空格,且无论两端的空格有多少个都会去掉,当然 中间的那些空格不会被去掉,如: String s = " a s f g ...