More than 2019 cattle off summer school camp (ninth field) H (Chairman of the tree + half)

Meaning of the questions:

There \ (n-\) length are \ (a_i \) of bamboo, there are \ (m \) operations, each operation you four numbers \ (L, R & lt, X, Y \) . Now you'll interval \ ([l, r] \ ) bamboo cut \ (Y \) knife, for each cut, you need to select a height \ (H \) , you will need interval \ ([l, r] \) in height of more than \ (h \) bamboo cut, eventually you need to ensure that every knifed same height. Now ask your first \ (x \) knife cut the required height.

analysis:

The meaning of the questions, one for \ (Query (L, R & lt, X, Y) \) , each knife cut the required height is fixed as \ (\ frac {\ sum_ { i = l} ^ {r} Y}} {a_i \) . Then when we are in the first \ (X \) during operations, it must have been cut \ (\ frac {\ sum_ { i = l} ^ {r} a_i * x} {y} \) height. And because every time we cut the height of the operation must be monotonically increasing, so we might as half of the \ (x \) times the height of cut required \ (Hei \) .

In order to determine the current \ (hei \) is legitimate, we need only according to the current height \ (hei \) , before calculating the total height was cut off \ (sumhei \) , and finally by comparing \ (sumhei \) and \ (\ frac {\ sum_ {i = l} ^ {r} a_i * x} {y} \) size to between.

And the required \ (sumhei \) , we need to know the interval \ ([l, r] \ ) , greater than a height equal to \ (Hei \) the number of tree \ (size \) and weight \ (Val \) , and let \ (val-size * hei \ ) that is the answer. The requirements of a number greater than the number and the size of the interval, we only need to look to the Chairman of tree maintenance.

Because President binary tree query set, so the whole time complexity is \ (\ mathcal {O} ( nlogn ^ 2) \)

Code:

#include <bits/stdc++.h>
#define maxn 200005
using namespace std;
typedef long long ll;
struct ST{
    int l,r,sz;
    ll val;
}tr[maxn*30];
int T[maxn],tot,n,m,a[maxn];
ll sum[maxn];
int update(int l,int r,int pre,int pos,int val){
    int rt=++tot;
    tr[rt]=tr[pre];
    tr[rt].val+=val;
    tr[rt].sz++;
    if(l==r) return rt;
    int mid=(l+r)>>1;
    if(pos<=mid) tr[rt].l=update(l,mid,tr[rt].l,pos,val);
    else tr[rt].r=update(mid+1,r,tr[rt].r,pos,val);
    return rt;
}
void query(int l,int r,int rt,int pre,int K,int &ans1,ll &ans2){
    if(l==r){
        ans1+=tr[rt].sz-tr[pre].sz;
        ans2+=tr[rt].val-tr[pre].val;
        return ;
    }
    int mid=(l+r)>>1;
    if(K<=mid){
        query(l,mid,tr[rt].l,tr[pre].l,K,ans1,ans2);
        ans1+=tr[tr[rt].r].sz-tr[tr[pre].r].sz;
        ans2+=tr[tr[rt].r].val-tr[tr[pre].r].val;
    }else query(mid+1,r,tr[rt].r,tr[pre].r,K,ans1,ans2);
    return;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        sum[i]=sum[i-1]+a[i];
        T[i]=update(1,100005,T[i-1],a[i],a[i]);
    }
    for(int i=1;i<=m;i++){
        int l,r,x,y;
        scanf("%d%d%d%d",&l,&r,&x,&y);
        double tmp=1.0*(sum[r]-sum[l-1])/y*x;
        double ll=0,rr=100005;
        for(int j=0;j<100;j++){
            double mid=(ll+rr)/2;
            int tt=ceil(mid),res1=0;
            long long res2=0;
            query(1,100005,T[r],T[l-1],tt,res1,res2);
            double ans=res2-res1*mid;
            if(ans<tmp) rr=mid;
            else ll=mid;
        }
        printf("%.8f\n",ll);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Chen-Jr/p/11360770.html