CF1199D. Welfare State 1600 ——思维*

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;
}
/*
 
 
 
 */

猜你喜欢

转载自blog.csdn.net/m0_59273843/article/details/120873949