zoukankan      html  css  js  c++  java
  • Cutting Bamboos 主席树+二分+前缀和

    二分第x次砍的位置,然后用线段树查询小于这个位置的数的个数和值的和。然后判断即可

    注意!!!主席树是通过动态开点实现的,本身已经不用再从1开始了,而本题开的范围也应该是0,100000 而不是1,100000(害得我找了很久的错误)

    #include<iostream>
    #include<string.h>
    #include<algorithm>
    #include<stdio.h>
    #include<math.h>
    #define LL long long
    using namespace std;
    const int maxx = 200007;
    const double eps = 1e-10;
    struct node{
       LL l,r,cnt;
       LL w;
    }tree[maxx<<5];
    LL root[maxx];
    LL a[maxx];
    LL pre[maxx];
    LL cnt;
    LL num;
    LL sumlength;
    void inserts(LL l,LL r,LL pre,LL &now,LL pos){
         now=++cnt;
         tree[now]=tree[pre];
         tree[now].cnt++;
         tree[now].w=tree[now].w+pos;
         if (l==r){
            return;
         }
         LL mid=(l+r)>>1;
         if (pos<=mid){
            inserts(l,mid,tree[pre].l,tree[now].l,pos);
         }else {
            inserts(mid+1,r,tree[pre].r,tree[now].r,pos);
         }
    }
    void query(LL L,LL R,LL l,LL r,LL pos){
       // if (l>pos)return;
        if (l==r){
            num+=(tree[R].cnt-tree[L].cnt);
            sumlength+=(tree[R].w-tree[L].w);
            return ;
        }
        LL mid=(l+r)>>1;
        if (pos<=mid){
           query(tree[L].l,tree[R].l,l,mid,pos);
        }else{
           num+=(tree[tree[R].l].cnt-tree[tree[L].l].cnt);
           sumlength+=(tree[tree[R].l].w-tree[tree[L].l].w);
           query(tree[L].r,tree[R].r,mid+1,r,pos);
        }
    }
    int main(){
      LL n,q;
       while(~scanf("%lld%lld",&n,&q)){
          pre[0]=0;
          cnt=0;
          for (int i=1;i<=n;i++){
            scanf("%lld",&a[i]);
            pre[i]=pre[i-1]+a[i];
            inserts(0,100000,root[i-1],root[i],a[i]);
          }
          LL ll,rr;
          LL x,y;
        while(q--){
          scanf("%lld%lld%lld%lld",&ll,&rr,&x,&y);
          double l=0,r=100000;
          double ans=0;
          while(fabs(r-l)>eps){
              double mid=(l+r)/2;
              num=0;
              sumlength=0;
              LL ss=floor(mid);
              query(root[ll-1],root[rr],0,100000,ss);
              num=(rr-ll+1)-num;
              double s=num*mid+sumlength;
              double step=1.0*(pre[rr]-pre[ll-1])/y;
              if (s-step*(y-x)>eps){
                r=mid;
              }else{
                l=mid;
              }
          }
          printf("%.10f
    ",l);
        }
       }
       return 0;
    }
    有不懂欢迎咨询 QQ:1326487164(添加时记得备注)
  • 相关阅读:
    用C++做微信公众平台开发的后台开发时,用sha1加密验证的方法
    UART Receive FIFO and Receive Timeout
    Compile cpp File Manually without IDE under Mingw Environment
    html5 返回当前地理位置的坐标点(经纬度)
    逆袭!花两个月吃透这份“MySQL宝典”拿到字节offer
    MySQL约束的概述
    2020-11-28
    人工智能能力提升指导总结
    年轻就该多尝试,教你20小时Get一项新技能
    MySQL~存储过程基本操作
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/11381454.html
Copyright © 2011-2022 走看看