传送门:Problem - 371D - Codeforces。
这题就是给你如上图所示的向下链接的容器,每一层都将给出最大容积。
接下来给出两种操作,第一种为向里面的某一层注入一定水。如果水满了就会向下漏,被下一层接住(在这里是立刻生效,不需要管时间问题),如果到了最后一层还有多余的水就掉地上不管了。
第二种为输出其中某一层的水的量。
思路:这种上下链接的关系不难想到并查集,这层满了就链接到下一层。然后问题来了,我们将会用一个数组存容积,那么输出什么东西或者说怎样操作会使我们方便判断与输出呢?在这里我们只需要多创建一个数组b,用注水量与容积数组和这个数组来比较,用b来存水即可。
代码如下:
#include<math.h>
#include<algorithm>
#include<time.h>
#include<stdlib.h>
#include<iostream>
#include<string.h>
#include<sstream>
#include<map>
#include<list>
#include<string>
#include<queue>
#include<set>
#include<vector>
#include<stack>
#include<limits>
#define re register
#define iosgo() std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define run(i,n) for (int i = 1; i <= n; i++)
#define cin std::cin
#define cout std::cout
#define ll long long
#define endl "\n"
using namespace std;
typedef pair<int, int>pll;
const int N = 2e6 + 10;
pll c[N];
int x[N], y[N], dp[N], ss[N], a[N], b[N];
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int find(int hg)
{
if (x[hg] == hg)return hg;
else return x[hg] = find(x[hg]);
}
void merge(int u, int v)
{
int f, g;
f = find(u);
g = find(v);
if (f != g)
{
x[f] = g;
}
}
signed main()
{
iosgo();
int n; cin >> n;
run(i, n)cin >> a[i], x[i] = i;
x[n + 1] = n + 1;
int m; cin >> m;
run(i, m)
{
int fg; cin >> fg;
if (fg == 1)
{
int q, w;
cin >> q >> w;
while (w)
{
q = find(q);
if (q == n + 1)break;
if (w == a[q] - b[q])
{
w -= a[q] - b[q];
b[q] = a[q];
}
else
if (w > a[q] - b[q])
{
w -= a[q] - b[q];
b[q] = a[q];
merge(q, q + 1);
q++;
q = find(q);
}
else
if (w < a[q] - b[q])
{
b[q] += w;
w = 0;
}
}
}
else
{
int s; cin >> s;
cout << b[s] << endl;
}
}
}