CF431E (权值线段树, 线段树上二分,动态开点)

https://www.luogu.com.cn/problem/CF431E

image

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);  
//#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
#define int long long
const int N = 1e5 + 5;
const int M = 1e6 + 5;
const int mod = 998244353;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const double PI = acos(-1.0);
struct SegTree {
  int lc, rc, cnt; ll sum;
} tree[N * 40 + 5];
int a[N], root, cur, sz;
void modify( ll pos, ll x, ll l, ll r, int & now) {
  if(!now) {
    now = ++ sz;
  }
  if(l == r) {
    tree[now].sum += x * pos; tree[now].cnt += x; return;
  }
  ll mid = l + r >> 1;
  if(pos <= mid) modify(pos, x, l, mid, tree[now].lc);
  else modify( pos, x, mid + 1, r,tree[now].rc);
  //pushup
  tree[now].sum = tree[tree[now].lc].sum + tree[tree[now].rc].sum;
  tree[now].cnt = tree[tree[now].lc].cnt + tree[tree[now].rc].cnt;
}
double query( ll val, ll l, ll r, int now) { // 访问到没有开的点 lc的cnt为0,会一直往大的跑,跑到一个大值能满足
  ll pcnt = 0, psum = 0;
  while(l != r) {
    ll mid = l + r >> 1;
    double sum = 1.0 * mid * (tree[tree[now].lc].cnt + pcnt) - tree[tree[now].lc].sum - psum; //乘法都可能爆longlong
    //加到mid(不包括mid)每柱加的不超过mid能加多少
    if( sum <= val ) l = mid + 1,  pcnt += tree[tree[now].lc].cnt, psum += tree[tree[now].lc].sum, now = tree[now].rc;
    else r = mid, now = tree[now].lc;
  }
  // 最终能填满k的高度,l和r在k + 1处相等,答案就是val删去前面填满k的,给k个柱再平均分配剩余的
  return 1.0 *(val - 1.0 * (l - 1) * (pcnt ) + psum ) / pcnt + l - 1;
}
signed main() {
  int n, q; cin >> n >> q;
  ll limit = 1e9; // 水银值域
  for ( int i = 1; i <= n; ++ i ) {
    cin >> a[i]; modify( a[i], 1,0, limit, root);
  }  
  while ( q -- ) {
    int opt, p, x;
    cin >> opt;
    if(opt == 1) {
      cin >> p >> x;
      modify(a[p], -1, 0, limit, root); //删旧加新
      modify(x, 1, 0, limit, root);
      a[p] = x;
    } else {
      ll x; cin >> x;
      printf("%.5lf\n", query(x, 0, limit, root));
    }

  }
  return 0;
}


posted @ 2022-04-27 21:54  qingyanng  阅读(35)  评论(0编辑  收藏  举报