每一个剪掉的高度是可以计算出拉爹,然后二分出高度,然后用主席树查询,大于这个高度的个数有多少个,乘以高度-二分的高度,然后与每一次需要剪掉的高度进行对比即可。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<climits>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<map>
//#include<regex>
#include<cstdio>
#define up(i,a,b) for(int i=a;i<b;i++)
#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef long long ll;
const double esp = 1e-6;
const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int inf = 1e9;
using namespace std;
ll read()
{
char ch = getchar(); int x = 0, f = 1;
while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
return x * f;
}
typedef pair<int, int> pir;
int n, q;
const int N = 200005;
struct tr {
ll l, r, num, sum; tr() { sum = 0; num = 0; }
}tree[N*40];
ll root[N];
ll a[N];
ll sum[N];
int cnt = 0;
void init()
{
cnt = 1;
root[0] = 0;
tree[0].l = tree[0].r = tree[0].sum = tree[0].num = 0;
}
void update(ll &pre, ll l, ll r, ll k)
{
tree[cnt] = tree[pre];
pre = cnt;
cnt++;
tree[pre].sum += a[k]; tree[pre].num++;
if (l == r)return;
ll mid = (l + r)/2;
if (a[k] <= mid)update(tree[pre].l, l, mid, k);
else update(tree[pre].r, mid + 1, r, k);
}
double searchfor(double k, ll l, ll r, ll a, ll b)
{
if (l == r)return 1.0*(tree[b].sum-tree[a].sum)-k*(tree[b].num-tree[a].num);
ll mid = (l + r)/2;
double temp = 1.0*(tree[tree[b].r].sum - tree[tree[a].r].sum) - k * (tree[tree[b].r].num - tree[tree[a].r].num);
//if (l == r)return temp;
if (k > mid)return searchfor(k, mid + 1, r,tree[a].r,tree[b].r);
else return temp+searchfor(k, l, mid, tree[a].l, tree[b].l);
}
int main()
{
n = read(), q = read();
upd(i, 1, n)
{
a[i] = read();
sum[i] = sum[i - 1] + a[i];
}
init();
upd(i, 1, n)
{
root[i] = root[i - 1];
update(root[i], 1, 100000, i);
}
// cout << tree[root[1]].sum << endl;
ll L, R, x, y;
while (q--)
{
L = read(), R = read(), x = read(), y = read();
double tmp = 1.0*(sum[R] - sum[L - 1])/y*x;
//cout << tmp << " ";
double lf = 0, rt = 100000;
up(i, 0, 100)
{
double mid = (lf + rt)/2.0;
double x1 = searchfor(mid, 1, 100000, root[L - 1], root[R]);
if (x1 < tmp)
rt = mid;
else lf = mid;
}
printf("%.10f\n",lf);
}
return 0;
}