zoukankan      html  css  js  c++  java
  • 2017 多校4 Dirt Ratio

    多校4 Dirt Ratio(二分+线段树)

    题意:

    给出n个数,找一段区间使得区间内不同数字个数除以区间长度最小,求这个最小值,(n<=60000,a_i<=n)

    题解:

    二分答案mid,检验是否存在一个区间满足(frac{size(l,r)}{r-l+1}leq mid ​),也就是(size(l,r)+mid imes lleq mid imes (r+1))

    从左往右枚举每个位置作(r),当rr变化为(r+1)时,对(size)的影响是一段区间加1,线段树维护区间最小值即可。

    时间复杂度(O(nlog nlog w))

    二分答案和枚举端点想到了,但是求最小值只会遍历,复杂度太高,没想到还能线段树维护,get新技能了。
    从左往右枚举右端点,那么第(i)个数的贡献就是(last[a[i]]+1到i),第i个数都是有贡献的,然后就用线段树搞搞,这样就降了一维复杂度了。

    #include<bits/stdc++.h>
    #define LL long long
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define ls (rt<<1)
    #define rs (rt<<1|1)
    using namespace std;
    const int N = 6e4 + 10;
    const double eps = 1e-6;
    int read(){
        int x = 0;
        char c = getchar();
        while(c < '0' || c >'9') c = getchar();
        while(c >= '0' && c <= '9') x = x * 10 + c - 48 , c = getchar();
        return x;
    }
    int n;
    int c[N],last[N],pre[N];
    double s[N<<2],col[N<<2];
    void pushup(int rt){
        s[rt] = min(s[ls],s[rs]);
    }
    void pushdown(int rt,int m){
        if(col[rt] > eps){
            col[ls] += col[rt];
            col[rs] += col[rt];
            s[ls] += col[rt];
            s[rs] += col[rt];
            col[rt] = 0;
        }
    }
    void update(int L,int R,double val,int l,int r,int rt){
        if(L <= l && R >= r){
            s[rt] += val;
            col[rt] += val;
            return ;
        }
        pushdown(rt,r - l + 1);
        int m = l + r >> 1;
        if(L <= m) update(L,R,val,lson);
        if(R > m) update(L,R,val,rson);
        pushup(rt);
    }
    double query(int L,int R,int l,int r,int rt){
        if(L <= l && R >= r){
            return s[rt];
        }
        pushdown(rt,r - l + 1);
        int m = l + r >> 1;
        double ans = 100000000;
        if(L <= m) ans = min(ans,query(L,R,lson));
        if(R > m) ans = min(ans,query(L,R,rson));
        return ans;
    }
    bool check(double mid){
        memset(s,0,sizeof(s));
        memset(col,0,sizeof(col));
        for(int i = 1;i <= n;i++){
            update(last[i]+1,i,1,1,n,1);
            update(i,i,mid * i,1,n,1);
            double res = query(1,i,1,n,1);
           // printf("%d %.6f
    ",i,res);
            if(mid * (i + 1) - res > eps) return true;
        }
        return false;
    }
    int main(){
    
        int T;
        T = read();
        while(T--){
          n = read();
          memset(pre,0,sizeof(pre));
          for(int i = 1;i <= n;i++) {
            c[i] = read();
            last[i] = pre[c[i]];
            pre[c[i]] = i;
          }
          double l = 0,r = 1,ans = r;
          while(r - l > eps){
            double mid = (l + r) / 2;
            if(check(mid)) ans = min(ans,mid),r = mid;
            else l = mid;
          }
          printf("%.6lf
    ",ans);
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    CSS盒子模型
    getContextPath、getServletPath、getRequestURI、request.getRealPath的区别
    MYSQL中的CASE WHEN END AS
    单点登录的精华总结
    git&github
    June 21st 2017 Week 25th Wednesday
    June 20th 2017 Week 25th Tuesday
    June 19th 2017 Week 25th Monday
    June 18th 2017 Week 25th Sunday
    June 17th 2017 Week 24th Saturday
  • 原文地址:https://www.cnblogs.com/jiachinzhao/p/7284439.html
Copyright © 2011-2022 走看看