zoukankan      html  css  js  c++  java
  • HDU 6070 Dirt Ratio(线段树、二分)

    http://acm.hdu.edu.cn/showproblem.php?pid=6070

    题解

      首先不难看出错误率是单调的,那么我们可以直接二分答案x,某个区间的错误率=区间数的种类cnt/区间长度r-l+1,变成:cnt+l*x<r*x+x;然后枚举区间区间右端点r,当前点影响的区间是le[i]+1到i,关于区间操作我们可以用线段树区间更新和区间查询最小值。

     1 #define dbg(x) cout<<#x<<" = "<< (x)<< endl
     2 #define IO std::ios::sync_with_stdio(0);
     3 #include <bits/stdc++.h>
     4 #define iter ::iterator
     5 using namespace  std;
     6 typedef long long ll;
     7 typedef pair<ll,ll>P;
     8 #define pb push_back
     9 #define se second
    10 #define fi first
    11 #define rs o<<1|1
    12 #define ls o<<1
    13 #define inf 0x3f3f3f3f
    14 const int N=6e4+5;
    15 int T,n;
    16 int a[N],add[N*4];
    17 double minv[N*4],x;
    18 void push(int o){
    19     minv[o]=min(minv[ls],minv[rs]);
    20 }
    21 void down(int o){
    22     if(add[o]){
    23         minv[ls]+=add[o];
    24         minv[rs]+=add[o];
    25         add[ls]+=add[o];
    26         add[rs]+=add[o];
    27         add[o]=0;
    28     }
    29 }
    30 void build(int o,int l,int r){
    31     add[o]=0;
    32     if(l==r){
    33         minv[o]=x*l;
    34         return;
    35     }
    36     int m=(l+r)/2;
    37     build(ls,l,m);
    38     build(rs,m+1,r);
    39     push(o);
    40 }
    41 void up(int o,int l,int r,int ql,int qr,int v){
    42     if(l>=ql&&r<=qr){
    43         add[o]+=v;
    44         minv[o]+=v;
    45         return;
    46     }
    47     down(o);
    48     int m=(l+r)/2;
    49     if(ql<=m)up(ls,l,m,ql,qr,v);
    50     if(qr>m)up(rs,m+1,r,ql,qr,v);
    51     push(o);
    52 }
    53 double qu(int o,int l,int r,int ql,int qr){
    54     if(l>=ql&&r<=qr){
    55         return minv[o];
    56     }
    57     int m=(l+r)/2;
    58     double res=1e9;
    59     down(o);
    60     if(ql<=m)res=min(res,qu(ls,l,m,ql,qr));
    61     if(qr>m)res=min(res,qu(rs,m+1,r,ql,qr));
    62     return res;
    63 }
    64 int pre[N],le[N];
    65 int check(){
    66     build(1,1,n);
    67     for(int i=1;i<=n;i++){
    68         up(1,1,n,le[i]+1,i,1);
    69         double res=qu(1,1,n,1,i);
    70         if(res<=x*(i+1))return 1;
    71     }
    72     return 0;
    73 }
    74 int main(){
    75     scanf("%d",&T);
    76     while(T--){
    77         scanf("%d",&n);
    78         memset(le,0,sizeof(le));
    79         memset(pre,0,sizeof(pre));
    80         for(int i=1;i<=n;i++){
    81             scanf("%d",&a[i]);
    82             le[i]=pre[a[i]];
    83             pre[a[i]]=i;
    84         }
    85         double l=0,r=1;
    86         for(int i=1;i<=30;i++){
    87             double m=(l+r)/2;
    88             x=m;
    89             if(check())r=m;
    90             else l=m;
    91         }
    92         printf("%.9lf
    ",x);
    93     }
    94 }
  • 相关阅读:
    晶振及COMS电路
    笔记16 C# typeof() & GetType()
    笔记15 修饰符
    笔记14 数据库编程技术
    C#基础知识
    C#连接数据库
    笔记13 winform
    笔记12 export to excel (NPOI)
    笔记11 export to excel
    笔记10
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/10785763.html
Copyright © 2011-2022 走看看