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 }
  • 相关阅读:
    如何生成a1,a2,a3,a4这样的变量名
    Swiper说明及API手册说明
    Centos下搭建 tomcat https服务器详解(原创)
    IOS 2D游戏开发框架 SpriteKit-->续(创建敌对精灵)
    AFNetworking 3.1
    IOS 2D游戏开发框架 SpriteKit-->续(postion,锚点,游戏滚动场景)
    动态加载HTML后使用query修改标签样式
    objective-c IOS应用更新
    Objective-c 动画
    java servlet上传centos服务器
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/10785763.html
Copyright © 2011-2022 走看看