题目链接:

https://codeforces.com/problemset/problem/1266/E

题目大意:

在游戏中要造宇宙飞船,需要 \(n\) 种材料,第 \(i\) 种材料需要 \(a_i\) 个。游戏更新了 \(q\) 个回合,每个回合会出现一个新的里程碑 (s, t, u),表示当有 \(t\)\(s\) 资源时,系统就会奖励一个 \(u\) 资源。如果后面出现的三元组的 s 和 t 与之前的某个三元组一样的话,后面的三元组会覆盖之前的三元组。问每个回合新的里程碑出现后,最少需要造几个资源。

思路:

刚开始时,需要造的资源数就是所有资源之和,当一个新的里程碑加入之后,需要造的资源数只有三种变化,减一、不变、或者加一。
当奖励的资源是我们需要的,那就可以少造一个;当奖励的资源是多余的,那就不变;当奖励的资源使我们还需要再造一个资源,即之前送的资源现在不送了,就得多造一个。
那么加入的里程碑可以分为两块来考虑,如果我们需要,可以少造一个,如果不需要,那就要多造或者不造,通过 \(map\) 来记录某条里程碑之前是否出现过,然后我们再用 \(cnt\) 数组记录该物品我们有了多少,就可以算最后的答案了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 2e5 + 10;
LL ans;
LL n, a[N], q, s, t, u, cnt[N];
map<LL, map<LL, LL>> mp;
void solve(){
	cin >> n;
	for (int i = 1; i <= n; i++){
		scanf("%d", &a[i]);
		ans += a[i];
	}
	cin >> q;
	while (q--){
		scanf("%d%d%d", &s, &t, &u);
		if (mp[s][t]){
			cnt[mp[s][t]]--;
			if (cnt[mp[s][t]] < a[mp[s][t]]) ans++;
			mp[s][t] = u;
			cnt[u]++;
			if (u != 0 && cnt[u] <= a[u]) ans--;
		}
		else{
			mp[s][t] = u;
			cnt[u]++;
			if (cnt[u] <= a[u]) ans--;
		}
		cout << ans << "\n";
	}
}
int main(){
	solve();
	return 0;
}
posted on 2022-01-11 15:31  Hamine  阅读(51)  评论(0编辑  收藏  举报