思路:
定义一个权值并查集,权值保存这个集合还可以存下多少水。
如果这个集合可以存放的水已经小于要装入的水,就将这个集合与下一个集合合并。
否则,直接把这个集合可以存放的水减去要装入的水的体积。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 200010;
int n, m;
int fa[N];
LL g[N], b[N];
int find(int x) {
if (x == fa[x]) return x;
return fa[x] = find(fa[x]);
}
int merge(int x, int y) {
int fx = find(x), fy = find(y);
if (fx == fy) return fx;
fa[fx] = fy;
g[fy] += g[fx];
return fy;
}
void init() {
for (int i = 1; i <= n; i++) fa[i] = i;
}
void modify(int x, LL v) {
x = find(x);
while (true) {
if (g[x] >= v || x >= n) break;
x = merge(x, x + 1);
}
g[x] = max(0ll, g[x] - v);
}
void query(int x) {
int fx = find(x);
if (fx == x) cout << b[x] - g[x] << '\n';
else cout << b[x] << '\n';
}
int main() {
#ifdef DEBUG
freopen("D:/Exercise/Test.in", "r", stdin);
clock_t st, ed;
cout << "===================START===================" << endl;
st = clock();
#endif
cin >> n;
for (int i = 1; i <= n; i++) cin >> g[i], b[i] = g[i];
init();
cin >> m;
int opt, a;
LL b;
for (int i = 1; i <= m; i++) {
cin >> opt;
if (opt == 1) { cin >> a >> b; modify(a, b); }
else { cin >> a; query(a); }
}
#ifdef DEBUG
ed = clock();
cout << "====================END====================" << endl;
cout << "Time:" << (ed - st) * 1.0 / CLOCKS_PER_SEC << " sec" << endl;
#endif
return 0;
}
标签:CF371D,return,fa,int,题解,fx,fy,find
From: https://www.cnblogs.com/PlayWithCPP/p/17399259.html