Cattle customer network and more training school ninth field H Cutting Bamboos

Topic link: https: //ac.nowcoder.com/acm/contest/889/H

The meaning of problems: given height, q n pieces of bamboo sub-query, query given every l, r, x, y, each select [l, r] in bamboo, bamboo cut all cut of y, each cut down bamboo and length are the same, ask your x-th which should cut down on height

Problem-solving ideas: As the total number of cut has been given, so we can know the chop chop x times the amount of total Total = $\sum\limits_{i=l}^{r}$h[i]*x/y,那么问题就变成了一个方程$\sum\limits_{i=l}^{r}$max(0,h[i]-ans)=Total,我们需要求的就是ans

That is greater than the number obtained in the range of minus ans ans is equal to Total, using the Chairman of the tree we can find a range larger than the number num and their number and sum, then we only need half ans verification can be. The time complexity of O ($nlog^{2}n$),后来我了解到一种更好的做法,

We need to access some interval greater than ans is to calculate the answer, we recursively processing this interval [L, R], first calculated in the right interval [M + 1, R] values ​​into the equation, then the value interval M (Why selected from the group M, as explained later) as the assumptions ans, then we can obtain a value of tmp, so val = Total

1, if tmp <Total, ans illustrate this election is too great, we need a smaller ans, therefore recursive processing of the current interval [L, M] to find a more suitable ans, then we need to make recursive val - = tmp, that is to say, we only need to pass the current offset value into account, to the left in the recursive interval [L, M], we continue to select the value interval ML hypotheses as ANS, then we need to recalculate tmp value, however, the current Total has a problem (it is a hypothesis ans = M calculated on based on), in order to correct Total, we just lost once in the calculation tmp added before the first num M (which is the current left range R, which is why select M as the reason for the assumption ans is, we can get the last hypothesis ans), then the current assumptions ans = ML recalculate the tmp value, note that we have to maintain a current has been selected the number of bamboo NUM , so that we can compute tmp, tmp after calculate the value, you can recursively

2, if tmp> Total, illustrate the ans selected too small, we need to go to the right interval [M + 1, R] is assumed to find a suitable back ans, so we maintain parameters constant interval to the right recursively

When we reach the end of recursion, L == R, described, if we assume the value of R is selected there is still a deviation val (val may be zero, but it does not matter), L-1 is selected will cause$\sum\limits_{i=l}^{r}$max(0,h[i]-ans)>Total,

因此我们可以根据这个偏差值val去修正假设的ans=L去得到真正的答案,真正的ans=L-val/(以及选取的所有竹子个数+高为L的竹子个数(以L为假设ans时,我们认为高为L的竹子是没有被砍的))时间复杂度O(nlogn)

AC Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5+5;
#define eps 1e-8
struct Node
{
    int l,r,num;
    ll sum;
}node[maxn*20];
int h[maxn],root[maxn],tot;
ll preSum[maxn];
void update(int &x,int y,int l,int r,int val)
{
    x=++tot;
    node[x]=node[y];
    ++node[x].num;
    node[x].sum+=val;
    if(l==r)return;
    int m=(l+r)>>1;
    if(val<=m)update(node[x].l,node[y].l,l,m,val);
    else update(node[x].r,node[y].r,m+1,r,val);
}
double query(int x,int y,int L,int R,double val,ll num)
{
    if(L==R)return L-val/(node[x].num-node[y].num+num);
    int m=(L+R)>>1;
    ll cnt=node[node[x].r].num-node[node[y].r].num;
    ll tmp=node[node[x].r].sum-node[node[y].r].sum-cnt*m+num*(R-m);
    if(tmp+eps<val)return query(node[x].l,node[y].l,L,m,val-tmp,num+cnt);
    return query(node[x].r,node[y].r,m+1,R,val,num);
}
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, q;
    cin >> n >> q;
    for (int i = 1; i <= n; i++) {
        cin >> h[i];
        preSum[i] = preSum[i - 1] + h[i];
        update(root[i], root[i - 1], 1, 1e5, h[i]);
    }
    while (q--) {
        int l, r, x, y;
        cin >> l >> r >> x >> y;
        printf("%.12f\n", query(root[r], root[l - 1], 1, 1e5, 1.0 * (preSum[r] - preSum[l - 1]) / Y * x, 0 )); 
    } 
    Return  0 ; 
}

 

Guess you like

Origin www.cnblogs.com/xusirui/p/11361534.html