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

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/15954421.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示