zoukankan      html  css  js  c++  java
  • 2019牛客暑期多校训练营(第九场)H Cutting BamboosO(二分、主席树)

    https://ac.nowcoder.com/acm/contest/889#question

    题意

    n个竹子排成一排,每次选一个高度切竹子,每次切下的总长度必须相等。

    q次查询,每次查询一个区间[l,r],x,y,表示在这个区间里切竹子,

    要保证一共切y次切完,问第x次切竹子的高度。

    题解

    一共要切掉的总长度为区间总长度len=x*S/y。

    对高度建主席树,二分一个整数高度h,使得高度>=h的竹子的总贡献<=len,

    然后把剩下的小数部分计算出来。

    代码很好写

     1 #define bug(x) cout<<#x<<" is "<<x<<endl
     2 #define IO std::ios::sync_with_stdio(0)
     3 #include <bits/stdc++.h>
     4 #define iter ::iterator
     5 #define pa pair<int,ll>
     6 using namespace  std;
     7 #define ll long long
     8 #define mk make_pair
     9 #define pb push_back
    10 #define se second
    11 #define fi first
    12 ll mod=998244353;
    13 const int N=2e5+5;
    14 int n,q;
    15 int cnt;
    16 int sum[N*22],ls[N*22],rs[N*22],rt[N];
    17 ll val[N*22];
    18 void up(int &o,int pre,int l,int r,int p){
    19     o=++cnt;
    20     val[o]=val[pre]+p;
    21     sum[o]=sum[pre]+1;
    22     ls[o]=ls[pre];
    23     rs[o]=rs[pre];
    24     if(l==r)return;
    25     int m=(l+r)/2;
    26     if(p<=m)up(ls[o],ls[pre],l,m,p);
    27     else up(rs[o],rs[pre],m+1,r,p);
    28 }
    29 ll cal(int o,int p){
    30     return val[o]-1ll*sum[o]*p;
    31 }
    32 ll qu(int o,int pre,int l,int r,int p){
    33     int m=(l+r)/2;
    34     if(p<=l)return cal(o,p)-cal(pre,p);
    35     ll res=qu(rs[o],rs[pre],m+1,r,p);
    36     if(p<=m)res+=qu(ls[o],ls[pre],l,m,p);
    37     return res;
    38 }
    39 int qu1(int o,int pre,int l,int r,int p){
    40     if(p<=l)return sum[o]-sum[pre];
    41     int m=(l+r)/2;
    42     int res=qu1(rs[o],rs[pre],m+1,r,p);
    43     if(p<=m)res+=qu1(ls[o],ls[pre],l,m,p);
    44     return res;
    45 }
    46 int main(){
    47     scanf("%d%d",&n,&q);
    48     int h=1e5;
    49     for(int i=1;i<=n;i++){
    50         int x;
    51         scanf("%d",&x);
    52         up(rt[i],rt[i-1],1,h,x);
    53     }
    54     while(q--){
    55         int ql,qr,x,y;
    56         cnt=0;
    57         scanf("%d%d%d%d",&ql,&qr,&x,&y);
    58         ll S=val[rt[qr]]-val[rt[ql-1]];
    59         int l=0,r=h;
    60         while(l<r){
    61             int m=(l+r)/2;
    62             ll res=qu(rt[qr],rt[ql-1],1,h,m);
    63             if(1.0*res/x<1.0*S/y)r=m;
    64             else l=m+1;
    65         }
    66         ll res=qu(rt[qr],rt[ql-1],1,h,l);
    67         double g=1.0*x/y*S-res;
    68         int res1=qu1(rt[qr],rt[ql-1],1,h,l);
    69         g/=res1;
    70         printf("%.10lf
    ",l-g);
    71     }
    72 }
  • 相关阅读:
    电子商务概论【0351】
    数据库原理
    建筑结构CAD[0753]
    计算机图像处理基础[9124]
    计算机基础[1056]
    计算机组成原理【0013】
    C语言程序设计【0039】
    计算机基础1056
    专业英语[0089]
    double数据转换成char字符串的函数——dtostrf()用法
  • 原文地址:https://www.cnblogs.com/ccsu-kid/p/11383014.html
Copyright © 2011-2022 走看看