zoukankan      html  css  js  c++  java
  • 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


    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(1T15), denoting the number of test cases.

    In each test case, there is an integer n(1n60000) in the first line, denoting the length of the submission list.

    In the next line, there are n positive integers a1,a2,...,an(1ain), 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 104.
     
    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[65003];
     23 int last[65003];
     24 map<int,int> mp;
     25 struct node
     26 {
     27     int l,r;
     28     double maxn;
     29     int add;
     30 } tree[500005];
     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=0;
     36     if(left==right)
     37     {
     38         tree[root].maxn=left*zz;
     39         return ;
     40     }
     41     int mid=(left+right)>>1;
     42     buildtree(root<<1,left,mid,zz);
     43     buildtree(root<<1|1,mid+1,right,zz);
     44     tree[root].maxn=min(tree[root<<1].maxn,tree[root<<1|1].maxn);
     45 }
     46 void pushdown(int root)
     47 {
     48     if(tree[root].add==0) return ;
     49     tree[root<<1].add+=tree[root].add;
     50     tree[root<<1|1].add+=tree[root].add;
     51     tree[root<<1].maxn+=tree[root].add;
     52     tree[root<<1|1].maxn+=tree[root].add;
     53     tree[root].add=0;
     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)>>1;
     65     if(right<=mid)
     66     {
     67         update(root<<1,left,right,c);
     68     }
     69     else
     70     {
     71         if(left>mid)
     72             update(root<<1|1,left,right,c);
     73         else
     74         {
     75             update(root<<1,left,mid,c);
     76             update(root<<1|1,mid+1,right,c);
     77 
     78         }
     79     }
     80     tree[root].maxn=min(tree[root<<1].maxn,tree[root<<1|1].maxn);
     81 }
     82 double query(int root,int left,int right)
     83 {
     84     if(left>right)
     85         return 0;
     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)>>1;
     92     if(right<=mid)
     93         return query(root<<1,left,right);
     94     else
     95     {
     96         if(left>mid)
     97             return query(root<<1|1,left,right);
     98         else
     99             return  min(query(root<<1,left,mid),query(root<<1|1,mid+1,right));
    100     }
    101 }
    102 bool check (double x)
    103 {
    104     buildtree(1,1,n,x);
    105     for(int i=1; i<=n; i++)
    106     {
    107         update(1,last[i]+1,i,1);
    108         double zha=(double)query(1,1,i);
    109         if(zha<=(i+1)*x)
    110             return true;
    111     }
    112     return false;
    113 }
    114 int main()
    115 {
    116     scanf("%d",&t);
    117     for(int kk=1;kk<=t;kk++){
    118     scanf("%d",&n);
    119     mp.clear();
    120     for(int i=1; i<=n; i++){
    121         scanf("%d",&a[i]);
    122         last[i]=mp[a[i]];
    123         mp[a[i]]=i;
    124     }
    125     double l=0,r=1.0,mid,ans;
    126     while(abs(l-r)>=0.00001)
    127     {
    128         mid=(l+r)/2;
    129         if(check(mid)){
    130             ans=mid;
    131             r=mid;
    132         }
    133         else
    134           l=mid;
    135     }
    136     printf("%f
    ",ans);
    137  }
    138     return 0;
    139 }
  • 相关阅读:
    windows10、windows server 2016激活方法
    .NET 和 .NET Core 使用 JWT 授权验证
    vs(vs2017、vs2019)离线安装包下载、制作
    VS顶部增加签名描述信息
    .NET WebAPI 跨域问题(has been blocked by CORS policy:No AccessControlAllowOgigin header is present on the requested resource)
    .Net 和 .Net Core 集成Swagger 以及配合JWT身份验证
    jQuery实现公告无限循环滚动
    甩掉 ashx/asmx,使用jQuery.ajaxWebService请求WebMethod,Ajax处理更加简练(转)
    JS和JQUERY常见函数封装方式
    第07组 Beta冲刺 (1/5)(组长)
  • 原文地址:https://www.cnblogs.com/hsd-/p/7281900.html
Copyright © 2011-2022 走看看