codeforces 1198B Welfare State 线段树

本文解析了CodeForces上的一道题目,该题目涉及线段树数据结构的应用,通过单点修改、区间修改和单点查询来解决一系列事件导致的财富变化问题。文章提供了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://codeforces.com/problemset/problem/1198/B
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.

Input
The first line contains a single integer n (1≤n≤2⋅105) — the numer of citizens.

The next line contains n integers a1, a2, …, an (0≤ai≤109) — the initial balances of citizens.

The next line contains a single integer q (1≤q≤2⋅105) — the number of events.

Each of the next q lines contains a single event. The events are given in chronological order.

Each event is described as either 1 p x (1≤p≤n, 0≤x≤109), or 2 x (0≤x≤109). In the first case we have a receipt that the balance of the p-th person becomes equal to x. In the second case we have a payoff with parameter x.

Output
Print n integers — the balances of all citizens after all events.

Examples
Input
4
1 2 3 4
3
2 3
1 2 2
2 1
Output
3 2 3 4
Input
5
3 50 2 1 10
3
1 2 0
2 8
1 3 20
Output
8 8 20 8 10
Note
In the first example the balances change as follows: 1 2 3 4 → 3 3 3 4 → 3 2 3 4 → 3 2 3 4

In the second example the balances change as follows: 3 50 2 1 10 → 3 0 2 1 10 → 8 8 8 8 10 → 8 8 20 8 10
题目大意: n n n个数,两种操作,(1)修改第 i i i个数的值。(2)把所有 &lt; x &lt;x <x的数变为 x x x。问最终的序列。
思路:单点修改+区间修改+单点查询,可以用线段树来做。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long ll;

const int maxn=2e5+5;

struct node
{
	int l,r,MIN,lazy;
}tree[maxn<<2];

void up(int i)
{
	tree[i].MIN=min(tree[i<<1].MIN,tree[i<<1|1].MIN);
}

void down(int i)
{
	tree[i<<1].lazy=max(tree[i<<1].lazy,tree[i].lazy);
	tree[i<<1|1].lazy=max(tree[i<<1|1].lazy,tree[i].lazy);
	tree[i<<1].MIN=max(tree[i].lazy,tree[i<<1].MIN);
	tree[i<<1|1].MIN=max(tree[i].lazy,tree[i<<1|1].MIN);
	tree[i].lazy=0;
}

void build(int i,int l,int r)
{
	tree[i].l=l,tree[i].r=r,tree[i].lazy=0;
	if(l==r)
	{
		scanf("%d",&tree[i].MIN);
		return ;
	}
	int mid=l+r>>1;
	build(i<<1,l,mid);
	build(i<<1|1,mid+1,r);
	up(i);
}

void update(int i,int pos,int v)
{
	if(tree[i].l==tree[i].r)
	{
		tree[i].MIN=v;
		return ;
	}
	if(tree[i].lazy)
		down(i);
	int mid=tree[i].l+tree[i].r>>1;
	if(pos<=mid)
		update(i<<1,pos,v);
	else
		update(i<<1|1,pos,v);
	up(i);
}

void update(int v)
{
	if(v<=tree[1].MIN)
		return ;
	tree[1].MIN=v;
	tree[1].lazy=max(tree[1].lazy,v);
}

int query(int i,int pos)
{
	if(tree[i].l==tree[i].r)
		return tree[i].MIN;
	if(tree[i].lazy)
		down(i);
	int mid=tree[i].l+tree[i].r>>1;
	if(pos<=mid)
		return query(i<<1,pos);
	else
		return query(i<<1|1,pos);
}

int main()
{
	int n,q,op,x,y;
	scanf("%d",&n);
	build(1,1,n);
	scanf("%d",&q);
	while(q--)
	{
		scanf("%d",&op);
		if(op==1)
		{
			scanf("%d %d",&x,&y);
			update(1,x,y);
		}
		else
		{
			scanf("%d",&x);
			update(x);
		}
	}
	for(int i=1;i<=n;i++)
	{
		printf("%d ",query(1,i));
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值