Codeforces Round #576 (Div. 2) D. Welfare State(简洁版代码)
总的题解里的写法有点乱,这里给出了(相对)简洁的写法
题意
给定一些数据,有两种操作,第一种是将指定位置的数改变成指定的数x,第二种是将所有比指定的数y小的数都变为y。给出执行完所有操作最后剩余的数据。
做法
记录每一次第二种操作的操作数,对每一次的第一种操作,记录他是在第几个第二次操作之后执行的,对记录第二种操作的操作数的数组从后往前进行相邻两项取max,然后对于每一个第一种操作,与它后一次的操作数进行比较,如果没有,则输出自身。
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int a[200010];
int sign[200010];
int changenumber[200010];
int main()
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
memset(sign,0,sizeof(sign)); //将所有的数组都标记为没有进行过第一种操作。
int q;
scanf("%d",&q);
int cnt = 0;
for(int i=0;i<q;i++)
{
int t;
scanf("%d",&t);
if(t==1)
{
int x,y;
scanf("%d%d",&x,&y);
sign[x] = cnt;
a[x] = y;
}
else
{
int x;
scanf("%d",&x);
changenumber[cnt++] = x;
}
}
for(int i=cnt-1;i>0;i--)
{
changenumber[i-1] = max(changenumber[i],changenumber[i-1]);
} //因为对于在某一次操作二之前进行的一操作,后面所有的二操作都会被再次执行,因此,我们不妨直接对后面所有的二操作进行后缀取max
for(int i=1; i<=n; i++)
{
if(a[i]<changenumber[sign[i]]&&sign[i]<cnt) printf("%d ",changenumber[sign[i]]);
else printf("%d ",a[i]);
}
}