CF1199D
题意:
给出n个公民的初始钱数,q次操作,1, x, y或2, p,前者使第x个公民钱数变为y,后者使所有小于p的钱全部变成p
问q次操作之后n个公民各有多少钱。
思路:
第一反应用线段树,维护每个区间的最小值,但实际上由于操作1是单点修改,所以没有必要
last[i]记录修改i节点的最后一个位置,b[i]代表从i时间点往后最大的补充x值
结果即在第i个数的最后一次1操作的x和最后一次1操作后面2操作最大的x中取最大值
// Decline is inevitable,
// Romance will last forever.
#include <bits/stdc++.h>
using namespace std;
#define mst(a, x) memset(a, x, sizeof(a))
#define INF 0x3f3f3f3f
#define mp make_pair
#define pii pair<int,int>
#define fi first
#define se second
#define ll long long
#define LL long long
//#define int long long
const int maxn = 2e5 + 10;
const int maxm = 1e3 + 10;
//const int P = 1e9 + 7;
int n;
int a[maxn];
int q;
int b[maxn], last[maxn]; //last[i]记录修改i节点的最后一个位置,b[i]代表从i时间点往后最大的补充x值
void solve() {
cin >> n;
for(int i = 1; i <= n; i++)
cin >> a[i];
cin >> q;
for(int i = 1; i <= q; i++) {
int ope;
cin >> ope;
if(ope == 1) {
int x, y;
cin >>x >> y;
a[x] = y;
last[x] = i;
}
else {
cin >> b[i];
}
}
for(int i = q-1; i >= 0; i--) {
b[i] = max(b[i+1], b[i]);
}
for(int i = 1; i <= n; i++)
cout << max(a[i], b[last[i]]) << ' ';
cout << endl;
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
// int T; scanf("%d", &T); while(T--)
// freopen("1.txt","r",stdin);
// freopen("output.txt","w",stdout);
// int T; cin >> T;while(T--)
solve();
return 0;
}
/*
*/