首先因为隔板的存在,所以整个水池开始是一坨一坨的,一共有 坨。
操作 就是把所有与
有交集的坨坨拿来进行合并,合并结果为总水量除以总池子数。
考虑用 set 维护,这样查询就是严格 级别的,我们来分析修改操作。
由于每次合并坨数都会减少 ,所以最多合并
次,均摊下来总复杂度为
,这样总复杂度就是
+
。足以通过此题。
the code:
#include <bits/stdc++.h>
#define L(i, a, b) for(int i = (a); i <= (b); i++)
#define R(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
using namespace std;
const int N = 500000 + 10;
int n, q; double a[N];
struct Node {
int l, r; double w;
bool operator < (const Node &T) const {
return l < T.l;
}
};
set<Node> S;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> q;
L(i, 1, n) cin >> a[i], S.insert({i, i, a[i]});
cout << fixed << setprecision(8);
while(q--) {
int op, l, r;
cin >> op;
if(op == 1) {
cin >> l >> r;
auto it = S.upper_bound({l, 0});
--it;
vector<set<Node>::iterator> vec;
double sum = 0; int R = r, L = it->l;
while(it != S.end() && it->l <= r) {
vec.push_back(it);
sum += it->w * (it->r - it->l + 1);
R = max(R, it->r);
it++;
}
for(auto x : vec) S.erase(x);
S.insert({L, R, sum / (R - L + 1)});
}
else {
cin >> l;
auto it = S.upper_bound({l, 0});
it--;
cout << it->w << '\n';
}
}
return 0;
}