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

Problem Description
In ACM/ICPC contest, the ''Dirt Ratio'' of a team is calculated in the following way. First let's ignore all the problems the team didn't pass, assume the team passed Xproblems during the contest, and submitted Y times for these problems, then the ''Dirt Ratio'' is measured as XY. If the ''Dirt Ratio'' of a team is too low, the team tends to cause more penalty, which is not a good performance.


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''.

 
Input
The first line of the input contains an integer T(1≤T≤15), denoting the number of test cases.

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.

 
Output
For each test case, print a single line containing a floating number, denoting the lowest ''Dirt Ratio''. The answer must be printed with an absolute error not greater than 10−4.
 
Sample Input
1
5
1 2 1 2 3
 
Sample Output
0.5000000000

Hint

For every problem, you can assume its final submission is accepted.

 
Source
 

题意:给你一个长度为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 比较

  1. #pragma comment(linker, "/STACK:102400000,102400000")
  2. #include <bits/stdc++.h>
  3. #include <cstdlib>
  4. #include <cstdio>
  5. #include <iostream>
  6. #include <cstdlib>
  7. #include <cstring>
  8. #include <algorithm>
  9. #include <cmath>
  10. #include <cctype>
  11. #include <map>
  12. #include <set>
  13. #include <queue>
  14. #include <bitset>
  15. #include <string>
  16. #include <complex>
  17. #define LL long long
  18. #define mod 1000000007
  19. using namespace std;
  20. int t;
  21. int n;
  22. int a[];
  23. int last[];
  24. map<int,int> mp;
  25. struct node
  26. {
  27. int l,r;
  28. double maxn;
  29. int add;
  30. } tree[];
  31. void buildtree(int root ,int left,int right,double zz)
  32. {
  33. tree[root].l=left;
  34. tree[root].r=right;
  35. tree[root].add=;
  36. if(left==right)
  37. {
  38. tree[root].maxn=left*zz;
  39. return ;
  40. }
  41. int mid=(left+right)>>;
  42. buildtree(root<<,left,mid,zz);
  43. buildtree(root<<|,mid+,right,zz);
  44. tree[root].maxn=min(tree[root<<].maxn,tree[root<<|].maxn);
  45. }
  46. void pushdown(int root)
  47. {
  48. if(tree[root].add==) return ;
  49. tree[root<<].add+=tree[root].add;
  50. tree[root<<|].add+=tree[root].add;
  51. tree[root<<].maxn+=tree[root].add;
  52. tree[root<<|].maxn+=tree[root].add;
  53. tree[root].add=;
  54. }
  55. void update(int root,int left,int right,int c)
  56. {
  57. if(tree[root].l==left&&tree[root].r==right)
  58. {
  59. tree[root].add+=c;
  60. tree[root].maxn+=c;
  61. return ;
  62. }
  63. pushdown(root);
  64. int mid=(tree[root].l+tree[root].r)>>;
  65. if(right<=mid)
  66. {
  67. update(root<<,left,right,c);
  68. }
  69. else
  70. {
  71. if(left>mid)
  72. update(root<<|,left,right,c);
  73. else
  74. {
  75. update(root<<,left,mid,c);
  76. update(root<<|,mid+,right,c);
  77.  
  78. }
  79. }
  80. tree[root].maxn=min(tree[root<<].maxn,tree[root<<|].maxn);
  81. }
  82. double query(int root,int left,int right)
  83. {
  84. if(left>right)
  85. return ;
  86. if(tree[root].l==left&&tree[root].r==right)
  87. {
  88. return tree[root].maxn;
  89. }
  90. pushdown(root);
  91. int mid=(tree[root].l+tree[root].r)>>;
  92. if(right<=mid)
  93. return query(root<<,left,right);
  94. else
  95. {
  96. if(left>mid)
  97. return query(root<<|,left,right);
  98. else
  99. return min(query(root<<,left,mid),query(root<<|,mid+,right));
  100. }
  101. }
  102. bool check (double x)
  103. {
  104. buildtree(,,n,x);
  105. for(int i=; i<=n; i++)
  106. {
  107. update(,last[i]+,i,);
  108. double zha=(double)query(,,i);
  109. if(zha<=(i+)*x)
  110. return true;
  111. }
  112. return false;
  113. }
  114. int main()
  115. {
  116. scanf("%d",&t);
  117. for(int kk=;kk<=t;kk++){
  118. scanf("%d",&n);
  119. mp.clear();
  120. for(int i=; i<=n; i++){
  121. scanf("%d",&a[i]);
  122. last[i]=mp[a[i]];
  123. mp[a[i]]=i;
  124. }
  125. double l=,r=1.0,mid,ans;
  126. while(abs(l-r)>=0.00001)
  127. {
  128. mid=(l+r)/;
  129. if(check(mid)){
  130. ans=mid;
  131. r=mid;
  132. }
  133. else
  134. l=mid;
  135. }
  136. printf("%f\n",ans);
  137. }
  138. return ;
  139. }

HDU 6070 二分+线段树的更多相关文章

  1. K-th occurrence HDU - 6704 (后缀数组+二分线段树+主席树)

    大意: 给定串s, q个询问(l,r,k), 求子串s[l,r]的第kk次出现位置. 这是一篇很好的题解: https://blog.csdn.net/sdauguanweihong/article/ ...

  2. hdu6070 Dirt Ratio 二分+线段树

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

  3. HDU4614 Vases and Flowers 二分+线段树

    分析:感觉一看就是二分+线段树,没啥好想的,唯一注意,当开始摆花时,注意和最多能放的比大小 #include<iostream> #include<cmath> #includ ...

  4. hdu 4031 attack 线段树区间更新

    Attack Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Subm ...

  5. hdu 4288 离线线段树+间隔求和

    Coder Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  6. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  7. J - Joseph and Tests Gym - 102020J (二分+线段树)

    题目链接:https://cn.vjudge.net/contest/283920#problem/J 题目大意:首先给你n个门的高度,然后q次询问,每一次询问包括两种操作,第一种操作是将当前的门的高 ...

  8. Educational Codeforces Round 61 D 二分 + 线段树

    https://codeforces.com/contest/1132/problem/D 二分 + 线段树(弃用结构体型线段树) 题意 有n台电脑,只有一个充电器,每台电脑一开始有a[i]电量,每秒 ...

  9. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

随机推荐

  1. ipmitool命令详解

    基础命令学习目录首页 原文链接:https://www.cnblogs.com/EricDing/p/8995263.html [root@localhost ~]# yum install -y i ...

  2. No.1001_第六次团队会议

    黯淡的一日 今天发生了很令人不爽的一件事,杜正远又被叫去实验室了.昨天界面就很难做,而且我们组人手稀缺,他的缺席让我很难做下去. 今天开会我自己没做出什么来,就加了一个群组的添加功能,同样,曾哲昊也没 ...

  3. 2017-2018-2 1723 『Java程序设计』课程 结对编程练习_四则运算

    一.结对对象 姓名:侯泽洋 学号:20172308 担任角色:驾驶员(侯泽洋) 伙伴第一周博客地址 二.本周内容 1.程序需求 (1).自动生成题目 可独立使用(能实现自己编写测试类单独生成题目的功能 ...

  4. 软件共享平台的NABCD

    Need: 我感觉我们这个软件很适合现在的大学生,特别是大一大二的学生,由于在大学里面学生都在各忙各的,学生遇到问题如果自己在网上查找,这就需要花费大量的时间,如果有了这个软件学生和老师都可以在这个平 ...

  5. 一个关于狗记录的Java练习

    package 狗场;import java.util.*;public class dogRoom { /** * 作者.范铭祥 * 狗场的狗体重查询问题 */ public static void ...

  6. 【转】Verilog HDL常用建模方式——《Verilog与数字ASIC设计基础》读书笔记(四)

    Verilog HDL常用建模方式——<Verilog与数字ASIC设计基础>读书笔记(四) Verilog HDL的基本功能之一是描述可综合的硬件逻辑电路.所谓综合(Synthesis) ...

  7. quartz任务管理

    导入quartz相关jar包后,要执行任务的类须实现Job接口 package quartz; import org.quartz.Job; import org.quartz.JobExecutio ...

  8. 【Linux笔记】CentOS 7 systemctl、firewalld

    一.CentOS7 systemctl 在CentOS7中,进行chkconfig命令操作时会发现有类似“systemctl.....”的提示,systemctl可以简单实现service和chkco ...

  9. BZOJ5089 最大连续子段和(分块)

    假设所有操作都是对整个序列的.考虑每个子区间,区间和与其被加的值构成一次函数关系.最大子段和相当于多个子区间取最大值,答案显然就在这些一次函数构成的下凸壳上.如果预处理出凸壳,只要在凸壳上暴力跳就可以 ...

  10. c# 方法参数 params 的试用

    //添加方法 public void test(params string[] messages) { } //调用方法 test("aaa","bbb",&q ...