维护一个权值线段树,然后二分答案。
#include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;} #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 vector<LL> oo; int getPos(double x) { return upper_bound(ALL(oo), x) - oo.begin(); } int cnt[N << 2]; LL sum[N << 2]; void update(int p, int op, int l, int r, int rt) { if(l == r) { cnt[rt] += op; sum[rt] += op * oo[p - 1]; return; } int mid = (l + r) >> 1; if(p <= mid) update(p, op, lson); else update(p, op, rson); cnt[rt] = cnt[rt << 1] + cnt[rt << 1 | 1]; sum[rt] = sum[rt << 1] + sum[rt << 1 | 1]; } PLI query(int L, int R, int l, int r, int rt) { if(L > R) return mk(0, 0); if(R < l || r < L) return mk(0, 0); if(L <= l && r <= R) return mk(sum[rt], cnt[rt]); int mid = (l + r) >> 1; PLI tmpL = query(L, R, lson); PLI tmpR = query(L, R, rson); return mk(tmpL.fi + tmpR.fi, tmpL.se + tmpR.se); } bool check(double tar, LL v) { PLI ret = query(1, getPos(tar), 1, SZ(oo), 1); return ret.se * tar - ret.fi > v; } int n, q; LL qus[N][3], h[N]; int main() { scanf("%d%d", &n, &q); for(int i = 1; i <= n; i++) { scanf("%d", &h[i]); oo.push_back(h[i]); } for(int i = 1; i <= q; i++) { scanf("%d", &qus[i][0]); if(qus[i][0] == 1) { scanf("%lld%lld", &qus[i][1], &qus[i][2]); oo.push_back(qus[i][2]); } else { scanf("%lld", &qus[i][1]); } } sort(ALL(oo)); oo.erase(unique(ALL(oo)), oo.end()); for(int i = 1; i <= n; i++) update(getPos(h[i]), 1, 1, SZ(oo), 1); for(int i = 1; i <= q; i++) { if(qus[i][0] == 1) { int p = qus[i][1], x = qus[i][2]; update(getPos(h[p]), -1, 1, SZ(oo), 1); h[p] = x; update(getPos(h[p]), 1, 1, SZ(oo), 1); } else { LL v = qus[i][1]; double low = 0, high = 1e9 + v + 1; for(int o = 0; o < 100; o++) { double mid = (low + high) / 2; if(check(mid, v)) high = mid; else low = mid; } printf("%.15f ", (low + high) / 2); } } return 0; } /* */