HDU 6070 二分+线段树
Dirt Ratio
Time Limit: 18000/9000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 335 Accepted Submission(s): 105
Special Judge

Picture from MyICPC
Little Q is a coach, he is now staring at the submission list of a team. You can assume all the problems occurred in the list was solved by the team during the contest. Little Q calculated the team's low ''Dirt Ratio'', felt very angry. He wants to have a talk with them. To make the problem more serious, he wants to choose a continuous subsequence of the list, and then calculate the ''Dirt Ratio'' just based on that subsequence.
Please write a program to find such subsequence having the lowest ''Dirt Ratio''.
In each test case, there is an integer n(1≤n≤60000) in the first line, denoting the length of the submission list.
In the next line, there are n positive integers a1,a2,...,an(1≤ai≤n), denoting the problem ID of each submission.
For every problem, you can assume its final submission is accepted.
题意:给你一个长度为n的区间 X=区间不同数的个数 Y=区间长度 求子区间X/Y的最小值
题解:二分答案mid check X/Y<=mid
X/Y=X/(r-L+1)<=mid
=> X+L*mid<=(r+1)*mid
建树初始每个点的maxn为L*mid
从左向右遍历右边界 遍历到r 更新(last[r]+1,r) 值增加1 last[r]表示a[r]相同值的上一个位置
r之前的每个结点L存的是L到r不同数的个数X+L*mid (这些便是不等式的左边)取最小值 与 (r+1)*mid 比较
#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <string>
#include <complex>
#define LL long long
#define mod 1000000007
using namespace std;
int t;
int n;
int a[];
int last[];
map<int,int> mp;
struct node
{
int l,r;
double maxn;
int add;
} tree[];
void buildtree(int root ,int left,int right,double zz)
{
tree[root].l=left;
tree[root].r=right;
tree[root].add=;
if(left==right)
{
tree[root].maxn=left*zz;
return ;
}
int mid=(left+right)>>;
buildtree(root<<,left,mid,zz);
buildtree(root<<|,mid+,right,zz);
tree[root].maxn=min(tree[root<<].maxn,tree[root<<|].maxn);
}
void pushdown(int root)
{
if(tree[root].add==) return ;
tree[root<<].add+=tree[root].add;
tree[root<<|].add+=tree[root].add;
tree[root<<].maxn+=tree[root].add;
tree[root<<|].maxn+=tree[root].add;
tree[root].add=;
}
void update(int root,int left,int right,int c)
{
if(tree[root].l==left&&tree[root].r==right)
{
tree[root].add+=c;
tree[root].maxn+=c;
return ;
}
pushdown(root);
int mid=(tree[root].l+tree[root].r)>>;
if(right<=mid)
{
update(root<<,left,right,c);
}
else
{
if(left>mid)
update(root<<|,left,right,c);
else
{
update(root<<,left,mid,c);
update(root<<|,mid+,right,c); }
}
tree[root].maxn=min(tree[root<<].maxn,tree[root<<|].maxn);
}
double query(int root,int left,int right)
{
if(left>right)
return ;
if(tree[root].l==left&&tree[root].r==right)
{
return tree[root].maxn;
}
pushdown(root);
int mid=(tree[root].l+tree[root].r)>>;
if(right<=mid)
return query(root<<,left,right);
else
{
if(left>mid)
return query(root<<|,left,right);
else
return min(query(root<<,left,mid),query(root<<|,mid+,right));
}
}
bool check (double x)
{
buildtree(,,n,x);
for(int i=; i<=n; i++)
{
update(,last[i]+,i,);
double zha=(double)query(,,i);
if(zha<=(i+)*x)
return true;
}
return false;
}
int main()
{
scanf("%d",&t);
for(int kk=;kk<=t;kk++){
scanf("%d",&n);
mp.clear();
for(int i=; i<=n; i++){
scanf("%d",&a[i]);
last[i]=mp[a[i]];
mp[a[i]]=i;
}
double l=,r=1.0,mid,ans;
while(abs(l-r)>=0.00001)
{
mid=(l+r)/;
if(check(mid)){
ans=mid;
r=mid;
}
else
l=mid;
}
printf("%f\n",ans);
}
return ;
}
HDU 6070 二分+线段树的更多相关文章
- K-th occurrence HDU - 6704 (后缀数组+二分线段树+主席树)
大意: 给定串s, q个询问(l,r,k), 求子串s[l,r]的第kk次出现位置. 这是一篇很好的题解: https://blog.csdn.net/sdauguanweihong/article/ ...
- hdu6070 Dirt Ratio 二分+线段树
/** 题目:hdu6070 Dirt Ratio 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意:给定n个数,求1.0*x/y最小是多少.x ...
- HDU4614 Vases and Flowers 二分+线段树
分析:感觉一看就是二分+线段树,没啥好想的,唯一注意,当开始摆花时,注意和最多能放的比大小 #include<iostream> #include<cmath> #includ ...
- hdu 4031 attack 线段树区间更新
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)Total Subm ...
- hdu 4288 离线线段树+间隔求和
Coder Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- J - Joseph and Tests Gym - 102020J (二分+线段树)
题目链接:https://cn.vjudge.net/contest/283920#problem/J 题目大意:首先给你n个门的高度,然后q次询问,每一次询问包括两种操作,第一种操作是将当前的门的高 ...
- Educational Codeforces Round 61 D 二分 + 线段树
https://codeforces.com/contest/1132/problem/D 二分 + 线段树(弃用结构体型线段树) 题意 有n台电脑,只有一个充电器,每台电脑一开始有a[i]电量,每秒 ...
- 【BZOJ-3110】K大数查询 整体二分 + 线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6265 Solved: 2060[Submit][Sta ...
随机推荐
- Mysql报错型注入总结
Mysql注入虽然是老生常谈的问题,但是工作中更多的是使用sqlmap等工具进行注入测试的,原理方面还是不是很清楚,所以这段时间主要是自己搭建环境在学手工注入,简单的将自己的学习做一个总结和记录.在常 ...
- 机器学习:数据预处理之独热编码(One-Hot)
前言 ———————————————————————————————————————— 在机器学习算法中,我们经常会遇到分类特征,例如:人的性别有男女,祖国有中国,美国,法国等.这些特征值并不是连续的 ...
- 使用python实现用微信远程控制电脑
首先,我们要先看看微信远程控制电脑的原理是什么呢? 我们可以利用Python的标准库控制本机电脑,然后要实现远程的话,我们可以把电子邮件作为远程控制的渠道,我们用Python自动登录邮箱检测邮件,当我 ...
- Scrum Meeting 2 -2014.11.2
今天大家读完代码后又聚在了一块讨论了许多.确定了重点的任务和分工细节.提出了许多问题和改进的方案.还有讨论分析了关于团队作业 - 软件分析和用户需求调查,初步决定目标软件为必应的输入法和词典,团队为争 ...
- 构造一个简单的Linux内核的MenuOS
构造一个简单的Linux内核的MenuOS 20135109 高艺桐 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000 ...
- 关于如何使用Microsoft Word发博客
关于如何使用Microsoft Word发博客 PS:以Microsoft Word 2010为例作具体操作,实际上Microsoft Word 2007也可以完成该功能,略有差异,但是只能是20 ...
- 20172325 2017-2018-2 《Java程序设计》第五周学习总结
20172325 2017-2018-2 <Java程序设计>第五周学习总结 教材学习内容总结 1.布尔表达式的值只有真或假,表达式的结果决定了下一步将要执行的语句. 2.循环语句可以用在 ...
- 第一个scrim任务分布
一.项目经理:郭健豪 二.scrim分工 杨广鑫.郭健豪:制作第一个精选页面布局,和代码实现.如:实现图书推荐布局中图书的排布,搜索框代码的实现,消息提示的跳转 李明.郑涛:实现第一个精选页面数据库的 ...
- n以内的1的个数
import java.util.Scanner; public class main { /** * @param args */ public static void main(String[] ...
- java的小学生四则运算
import java.awt.*; import java.awt.event.*; import java.io.FileNotFoundException; import java.io.IOE ...