题目链接
题目大意
有n个数,m次操作:
1 x y 的意思是把第x个数改为y
2 x 的意思是把这n个数所有小于x的数都改为x
解题思路
先建一棵线段树,用add表示这个数应该不小于add,就和之前的lazy差不多,遇到就往下传,只不过要传最大的那个
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=2e5+5;
int a[N];
struct node
{
int l,r,sum,add;
};
node e[N*4];
void build(int root,int l,int r)
{
e[root].l=l;
e[root].r=r;
e[root].add=e[root].sum=0;
if(l==r)
{
e[root].sum=a[l];
return ;
}
build(root*2,l,(l+r)/2);
build(root*2+1,(l+r)/2+1,r);
}
void updown(int root)
{
if(e[root].add)
{
e[root*2].add=max(e[root*2].add,e[root].add);
e[root*2+1].add=max(e[root*2+1].add,e[root].add);
e[root].add=0;
}
}
void update(int root,int x,int y)
{
if(e[root].l==e[root].r)
{
e[root].add=0;
e[root].sum=y;
return ;
}
updown(root);
int mid=(e[root].l+e[root].r)/2;
if(x<=mid)
update(root*2,x,y);
else
update(root*2+1,x,y);
}
int que(int root,int x)
{
if(e[root].l==e[root].r)
{
return max(e[root].add,e[root].sum);
}
updown(root);
int mid=(e[root].l+e[root].r)/2;
if(x<=mid)
return que(root*2,x);
else
return que(root*2+1,x);
}
int main()
{
int n,m,x,y,z;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,1,n);
scanf("%d",&m);
while(m--)
{
scanf("%d",&z);
if(z==1)
{
scanf("%d %d",&x,&y);
update(1,x,y);
}
else
{
scanf("%d",&x);
e[1].add=max(e[1].add,x);
}
}
for(int i=1;i<=n;i++)
{
printf("%d%c",que(1,i),i==n?'\n':' ');
}
return 0;
}