Ninth Event F Popping Balloons of Niukeduo University in 2019
To give you a number of trees of h height, and then hacked y times, just to cut all the trees, every time they cut all the trees across the tree, demanding that every time the height of all trees was cut down, what height was cut at x times?
Solution: Presidential Tree + Dichotomy
A: The dichotomy here is not very rigorous. It mainly uses the recursive search of the presidential tree.
B: Pay attention to the problem of accuracy (eps) in the query. Then I use the recursive method to build the chairman tree. It's not very recommended, but it's better to write. There are some recursive ways to write the title meeting card. (I'll post a non-recursive script sometime)
C: The answer can be obtained by dividing the answer.
Gossip: I haven't written the chairman tree for a long time. I'm a bit handy. I'm going to find some topics to practice my hands. I'll come back and fill in this problem.
Code:
#include<cstdio> #include<string> #include<cstring> #include<iostream> #include<vector> #include<algorithm> using namespace std; typedef long long ll; const int mx = 1e5 + 7; const double eps = 1e-9; struct node { ll sum, num; int l, r; }tree[mx * 40 * 2]; int root[mx * 40 * 2]; ll cnt = 0; void update(int l, int r, int &x, int y, int h) { tree[++cnt] = tree[y]; tree[cnt].num++; tree[cnt].sum += h; x = cnt; if (l == r) return; int mid = (l + r) / 2; if (mid >= h) update(l, mid, tree[x].l, tree[y].l, h); else update(mid + 1, r, tree[x].r, tree[y].r, h); } double query(int l, int r, int x, int y, double s, int nm) { if (l == r){ return s / (tree[y].num - tree[x].num + nm); } int mid = (l + r) / 2; ll lson = tree[tree[y].l].sum - tree[tree[x].l].sum; ll nn = tree[tree[y].r].num - tree[tree[x].r].num + nm; ll rson = mid * nn; if (lson + rson - s > eps) return query(l, mid, tree[x].l, tree[y].l, s, nn); else return query(mid + 1, r, tree[x].r, tree[y].r, s - lson, nm); } int main() { int n, m, x, y, u, v; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { ll re; scanf("%lld", &re); update(1, mx, root[i], root[i - 1],re); } for (int i = 1; i <= m; i++) { scanf("%d%d%d%d", &u, &v, &x, &y); double rest = 1.0 * (tree[root[v]].sum - tree[root[u - 1]].sum) * (1 - 1.0 * x / y); double ans = query(1, mx, root[u-1], root[v], rest, 0); printf("%.15lf\n", ans); } return 0; }