CodeForces 431E Chemistry Experiment

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
using LL = long long;
const int N = 100001;
const LL INF = 1e15;
const double EPS = 1e-5;
int n, m, op, x, a[N];
LL val;
vector<double> nums;
struct Node {
int l, r, cnt;
LL sum;
} tr[N << 3];
struct Q {
int op, x;
LL val;
} ques[N];
int find(int x) {
return lower_bound(nums.begin(), nums.end(), x) - nums.begin();
}
void pushup(int u) {
tr[u].cnt = tr[u << 1].cnt + tr[u << 1 | 1].cnt;
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void build(int u, int l, int r) {
tr[u] = {l, r, 0, 0};
if (l == r) return;
int mid = (l + r) >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}
pair<int, LL> query(int u, int l, int r) {
if (l <= tr[u].l && tr[u].r <= r) return {tr[u].cnt, tr[u].sum};
int c = 0, mid = (tr[u].l + tr[u].r) >> 1;
LL s = 0;
if (l <= mid) {
auto [cnt, sum] = query(u << 1, l, r);
c = cnt, s = sum;
}
if (r > mid) {
auto [cnt, sum] = query(u << 1 | 1, l, r);
c += cnt, s += sum;
}
return {c, s};
}
void solve(LL x) {
double l = 0, r = INF, res = 0;
while (r - l >= EPS) {
double mid = (l + r) / 2;
int p = upper_bound(nums.begin(), nums.end(), mid) - nums.begin();
auto [cnt, sum] = query(1, 1, p);
if (cnt * mid >= sum + x) r = res = mid;
else l = mid;
}
printf("%.5f\n", res);
}
void modify(int u, int x, int k) {
if (tr[u].l == tr[u].r) {
tr[u].cnt += k, tr[u].sum += (nums[x - 1] * k);
} else {
int mid = (tr[u].l + tr[u].r) >> 1;
if (x <= mid) modify(u << 1, x, k);
else modify(u << 1 | 1, x, k);
pushup(u);
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), nums.push_back(a[i]);
for (int i = 1; i <= m; ++i) {
scanf("%d", &op);
if (op == 1) {
scanf("%d%lld", &x, &val);
ques[i] = {1, x, val};
nums.push_back(val);
} else {
scanf("%lld", &val);
ques[i] = {0, 0, val};
}
}
sort(nums.begin(), nums.end());
nums.erase(unique(nums.begin(), nums.end()), nums.end());
build(1, 1, nums.size());
for (int i = 1; i <= n; ++i) modify(1, find(a[i]) + 1, 1);
for (int i = 1; i <= m; ++i) {
auto &[op, x, val] = ques[i];
if (op == 1) {
modify(1, find(a[x]) + 1, -1);
a[x] = val;
modify(1, find(a[x]) + 1, 1);
} else solve(val);
}
return 0;
}
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
#include <cstdio>
#include <utility>
using namespace std;
using LL = long long;
const int N = 100001;
const LL INF = 1e15;
const double EPS = 1e-5;
int n, m, op, x, a[N], mx = 1e9 + 10, idx = 1;
LL val;
struct Node {
int l, r, cnt;
LL sum;
} tr[N * 100];
void pushup(int u) {
tr[u].cnt = tr[tr[u].l].cnt + tr[tr[u].r].cnt;
tr[u].sum = tr[tr[u].l].sum + tr[tr[u].r].sum;
}
pair<int, LL> query(int u, int l, int r, double L, double R) {
if (L <= l && r <= R) return {tr[u].cnt, tr[u].sum};
int c = 0, mid = (l + r) >> 1;
LL s = 0;
if (L <= mid && tr[u].l) {
auto [cnt, sum] = query(tr[u].l, l, mid, L, R);
c = cnt, s = sum;
}
if (R > mid && tr[u].r) {
auto [cnt, sum] = query(tr[u].r, mid + 1, r, L, R);
c += cnt, s += sum;
}
return {c, s};
}
void solve(LL x) {
double l = 0, r = INF;
while (r - l >= EPS) {
double mid = (l + r) / 2;
if (mid >= mx) {
if (tr[1].cnt * mid >= tr[1].sum + x) r = mid;
else l = mid;
} else {
auto [cnt, sum] = query(1, 0, mx, 0, mid);
if (cnt * mid >= sum + x) r = mid;
else l = mid;
}
}
printf("%.5f\n", l);
}
void modify(int u, int l, int r, int x, int k) {
if (l == r) {
tr[u].cnt += k, tr[u].sum += x * k;
} else {
int mid = (l + r) >> 1;
if (x <= mid) {
if (!tr[u].l) tr[u].l = ++idx;
modify(tr[u].l, l, mid, x, k);
} else {
if (!tr[u].r) tr[u].r = ++idx;
modify(tr[u].r, mid + 1, r, x, k);
}
pushup(u);
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), modify(1, 0, mx, a[i], 1);
while (m--) {
scanf("%d", &op);
if (op == 1) {
scanf("%d%lld", &x, &val);
modify(1, 0, mx, a[x], -1);
a[x] = val;
modify(1, 0, mx, a[x], 1);
} else {
scanf("%lld", &val);
solve(val);
}
}
return 0;
}