There is a country with n citizens. The i-th of them initially has ai money. The government strictly controls the wealth of its citizens. Whenever a citizen makes a purchase or earns some money, they must send a receipt to the social services mentioning the amount of money they currently have.
Sometimes the government makes payouts to the poor: all citizens who have strictly less money than x are paid accordingly so that after the payout they have exactly x money. In this case the citizens don’t send a receipt.
You know the initial wealth of every citizen and the log of all events: receipts and payouts. Restore the amount of money each citizen has after all events.
题意:n
个数,q
个操作。操作有两种:
1 p x
:将p
点的数字改为x
;2 x
:将所有小于x
的数改为x
。
思路:明显的线段树单点和区间修改,单点查询。建一个维护最小值的线段树方便区间修改。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 2e5+5;
struct node
{
int l, r;
int value;
int lazy;
node(){l = r = value = lazy = 0;}
}T[maxn<<2];
void Push_Down(int cur)
{
int lazy = T[cur].lazy;
T[cur].lazy = 0;
T[cur<<1].value > lazy ? T[cur<<1].value : (T[cur<<1].lazy = lazy, T[cur<<1].value = lazy);
T[cur<<1|1].value > lazy ? T[cur<<1|1].value : (T[cur<<1|1].lazy = lazy, T[cur<<1|1].value = lazy);
}
void build(int l, int r, int cur)
{
T[cur].l = l; T[cur].r = r;
if(l == r)
{
scanf("%d", &T[cur].value);
return ;
}
int mid = (l+r)>>1;
build(l, mid, cur<<1);
build(mid+1, r, cur<<1|1);
T[cur].value = min(T[cur<<1].value, T[cur<<1|1].value);
}
void Update_Seg(int l, int r, int _left, int _right, int cur, int val)
{
if(_left <= l && r <= _right)
{
if(T[cur].value >= val) return ;
T[cur].value = val;
T[cur].lazy = val;
}
Push_Down(cur);
int mid = (l+r)>>1;
if(_right <= mid) Update_Seg(l, mid, _left, _right, cur<<1, val);
else if(_left > mid) Update_Seg(mid+1, r, _left, _right, cur<<1|1, val);
T[cur].value = min(T[cur<<1].value, T[cur<<1|1].value);
}
void Update_Point(int l, int r, int pos, int cur, int val)
{
if(l == r)
{
T[cur].value = val;
return ;
}
Push_Down(cur);
int mid = (l+r)>>1;
if(pos <= mid) Update_Point(l, mid, pos, cur<<1, val);
else Update_Point(mid+1, r, pos, cur<<1|1, val);
T[cur].value = min(T[cur<<1].value, T[cur<<1|1].value);
}
int Get(int l, int r, int pos, int cur)
{
if(l == r) return T[cur].value;
int mid = (l+r)>>1;
Push_Down(cur);
if(pos <= mid) return Get(l, mid, pos, cur<<1);
else return Get(mid+1, r, pos, cur<<1|1);
}
int main()
{
int n, q;
cin >> n;
build(1, n, 1);
cin >> q;
while(q--)
{
int op, x, p;
scanf("%d", &op);
if(op == 1)
{
scanf("%d%d", &p, &x);
Update_Point(1, n, p, 1, x);
}
else
{
scanf("%d", &x);
Update_Seg(1, n, 1, n, 1, x);
}
}
for(int i = 1; i <= n; i++)
{
if(i == 1) printf("%d", Get(1, n, i, 1));
else printf(" %d", Get(1, n, i, 1));
}
cout << endl;
return 0;
}