1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
| #include <bits/stdc++.h> using namespace std; typedef long long ll; const double eps = 1e-10; const int MAXN = 200005; struct node{ int l,r; ll sum, num; }tr[MAXN * 40]; int rt[MAXN],h[MAXN],tot; ll sum_pre[MAXN]; void build(int &o, int l, int r) { o = ++tot; tr[o].num = 0, tr[o].sum = 0; if(l == r) return; int mid = (l + r) >> 1; build(tr[o].l, l, mid); build(tr[o].r, mid + 1, r); }
void update(int &o, int last, int l, int r, int pos) { o = ++tot; tr[o].l = tr[last].l; tr[o].r = tr[last].r; tr[o].num = tr[last].num + 1; tr[o].sum = tr[last].sum + pos; if(l == r) return; int mid = (l + r) >> 1; if(pos <= mid ) update(tr[o].l, tr[last].l, l, mid, pos); else update(tr[o].r, tr[last].r,mid + 1, r, pos); } ll sum, num;
void query(int &o, int last, int l, int r, int k) { if(k < l) return; if(k >= r) { sum += tr[o].sum - tr[last].sum; num += tr[o].num - tr[last].num; return; } int mid = (l + r) >> 1; query(tr[o].l, tr[last].l, l, mid, k); query(tr[o].r, tr[last].r, mid + 1, r, k); } int main() { int n, m; scanf("%d%d",&n,&m); build(rt[0], 1, 100000); for(int i = 1; i <= n; ++i) { scanf("%d",&h[i]); update(rt[i], rt[i - 1], 1, 100000, h[i]); sum_pre[i] = sum_pre[i - 1] + h[i]; } while(m--) { int L, R, x, y; scanf("%d%d%d%d",&L,&R,&x,&y); double zong = sum_pre[R] - sum_pre[L - 1]; double standard = zong - (zong * 1.0 )/y * x; double l = 0, r = 100000; while(r - l > eps) { double mid = (l + r) / 2; sum = 0, num = 0; query(rt[R], rt[L - 1], 1, 100000, (int)mid); double num1 = (sum + (R - L + 1 - num) * mid); if(num1 > standard) r = mid; else l = mid; } printf("%.15f\n", l); } }
|