题面链接:传送门
题意描述:
Levko非常喜欢数组,他对数组有两种操作:
1、给出区间l和r,给一个价值v,区间里面的值都加上v:
2、给你一个区间l和r,找出这个区间内数值最大的数。
但Levko非常粗心,把原本的数组忘记了,只有操作的步骤和结果,问你能不能得到一个数组满足上述的操作。
题意分析:
这道题的解法应该从给出的操作逆序求解,因为数组的大小是|ai| ≤ 1e9,所以先把数组a全部赋值为1e9+5,即inf。然后按操作往上求解,遇到操作1,就把区间内数组不是inf的值减去v。遇到操作2的话,就在区间运行a[i] = min(a[i], v)的操作,因为操作2是查询区间最大值的,所以区间内小于v的值可以不用管,大于v的值就赋值为v。最后得到的数组a[i]里面数组为inf的值赋值为-1e9。然后再顺序判断是否符合上面操作就行了。
代码:
#include<bits/stdc++.h>
using namespace std;
int n, m;
struct dd{
int type, l, r, value;
}node[5005];
int ans[5005], a[5005];
const int inf = 1e9+5;
int main(){
cin >> n >> m;
memset(a, inf, sizeof(a));
for(int i=1;i<=m;++i){
scanf("%d %d %d %d", &node[i].type, &node[i].l, &node[i].r, &node[i].value);
}
for(int i=m;i>0;--i){
if(node[i].type == 1){
for(int j = node[i].l; j<=node[i].r;++j){
if(a[j] != inf) a[j] -= node[i].value;
}
}else{
for(int j=node[i].l;j<=node[i].r;++j){
a[j] = min(node[i].value, a[j]);
}
}
}
for(int i=1;i<=n;++i){
if(a[i] == inf) a[i] = -1e9;
ans[i] = a[i];
}
/*
for(int i=1;i<n;++i)cout << ans[i] << " ";
cout << ans[n] << endl;*/
int flag = 0;
for(int i=1;i<=m;++i){
if(node[i].type == 1){
for(int j=node[i].l;j<=node[i].r;++j){
a[j] += node[i].value;
}
}else{
int cnt = -inf;
for(int j=node[i].l;j<=node[i].r;++j){
cnt = max(cnt, a[j]);
}
if(cnt != node[i].value) {flag = 1; break;}
}
}
if(flag) cout << "NO" << endl;
else{
cout << "YES" << endl;
for(int i=1;i<n;++i) {
printf("%d ", ans[i]);
}
printf("%d\n", ans[n]);
}
return 0;
}