B. Welfare State

题目链接

B. Welfare State

一个数组,两种操作,然后输出最终数组,两种操作是:
1 p x: 表示将第 \(p\) 个数改为 \(x\)
2 x: 表示将所有小于 \(x\) 的数改成 \(x\)

解题思路

思维

首先可以肯定的一点:后面的 \(2\) 操作可能会对前面的值产生影响,这种影响有后往前取最大值即可,而操作 \(1\) 与顺序有关,可以记录操作 \(1\) 最后一次的影响,如果后面有操作 \(2\),取两者影响的最大值即可,注意,如果某个位置的数没有经过单点修改的话则取操作 \(2\) 的最大值

  • 时间复杂度:\(O(n)\)

线段树

关键在于操作 \(2\),即对于值域的修改,打懒标记,由于是全局性的修改,直接对根节点打上懒标记即可,另外注意线段树的写法

  • 时间复杂度:\(O(qlogn)\)

代码

  • 思维
// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=1e6+5;
int n,q,lst[N],a[N],b[N];
int main()
{
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=q;i++)
    {
    	int op,x,y;
    	scanf("%d",&op);
    	if(op==1)
    	{
    		scanf("%d%d",&x,&y);
    		a[x]=y;
    		lst[x]=i;
    	}
    	else
    	{
    		scanf("%d",&x);
    		b[i]=x;
    	}
    }
    for(int i=q-1;~i;i--)b[i]=max(b[i],b[i+1]);
    for(int i=1;i<=n;i++)printf("%d ",max(a[i],b[lst[i]]));
    return 0;
}
  • 线段树
// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=1e6+5;
int n,q;
struct Tr
{
	int l,r,val,lazy;
}tr[4*N];
void pushup(int p)
{
	tr[p].val=max(tr[p<<1].val,tr[p<<1|1].val);
}
void pushdown(int p)
{
	if(tr[p].lazy)
	{
		int &add=tr[p].lazy;
		tr[p<<1].val=max(tr[p<<1].val,add);
		tr[p<<1|1].val=max(tr[p<<1|1].val,add);
		tr[p<<1].lazy=max(tr[p<<1].lazy,add);
		tr[p<<1|1].lazy=max(tr[p<<1|1].lazy,add);
		add=0;
	}
}
void build(int p,int l,int r)
{
	tr[p]={l,r,0,0};
	if(l==r)
	{
		scanf("%d",&tr[p].val);
		tr[p].lazy=tr[p].val;
		return ;
	}
	int mid=l+r>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	pushup(p);
}
void change1(int p,int l,int r,int x,int y)
{
	if(l==r)
	{
		tr[p].val=y;
		return ;
	}
	pushdown(p);
	int mid=l+r>>1;
	if(x<=mid)change1(p<<1,l,mid,x,y);
	else
		change1(p<<1|1,mid+1,r,x,y);
	pushup(p);
}
void change2(int p,int y)
{
	tr[p].lazy=max(tr[p].lazy,y);
	tr[p].val=max(tr[p].val,y);
}
int ask(int p,int l,int r,int x)
{
	if(l==r)return tr[p].val;
	pushdown(p);
	int mid=l+r>>1;
	if(x<=mid)return ask(p<<1,l,mid,x);
	else
		return ask(p<<1|1,mid+1,r,x);
	pushup(p);
}
int main()
{
    scanf("%d%d",&n,&q);
    build(1,1,n);
    while(q--)
    {
    	int op,x,y;
    	scanf("%d",&op);
    	if(op==1)
    	{
    		scanf("%d%d",&x,&y);
    		change1(1,1,n,x,y);
    	}
    	else
    	{
    		scanf("%d",&y);
    		change2(1,y);
    	}
    }
    for(int i=1;i<=n;i++)printf("%d ",ask(1,1,n,i));
    return 0;
}
posted @ 2022-03-02 11:52  zyy2001  阅读(12)  评论(0编辑  收藏  举报