题目链接:https://codeforces.com/problemset/problem/360/A
题目大意:
Levko很喜欢整数数组,他正玩着一个由n个整数组成的数组a。他玩耍时有两种操作:1、[l, r]所有元素+d; 2、求[l, r]区间最大值。无可奈何的是Levko忘了原来的数组,但是他知道每次操作以及其结果,而且数组元素大小不会超过1e9。现在他求你找到原来的数组,符合条件即可。
解题思路:
知道了每一次操作及其结果,我们不妨逆向处理出一个数组,随后再正向检验一遍。但是要注意两个细节问题:1、构造的数组每个元素初始化为1e9,这里有点贪心的思想,如此一来区间最大值在逆向操作2只减不增,不会破坏其他区间最大值; 2、在逆向执行操作1时,不能使构造的数组值大于1e9,否则会出错。
代码如下:
# include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
const int inf = 1e9;
struct node{
int op, l, r, w;
}ope[maxn];
int num[maxn], ans[maxn];
int n, m;
int main(){
std::ios::sync_with_stdio(false);
while(cin >> n >> m){
for(int i = 0; i < m; ++i)
cin >> ope[i].op >> ope[i].l >> ope[i].r >> ope[i].w;
for(int i = 0; i <= n; ++i) num[i] = inf;
for(int i = m-1; i >= 0; --i){
if(ope[i].op == 1){
for(int j = ope[i].l; j <= ope[i].r; ++j)
if(num[j] - ope[i].w <= inf) num[j] -= ope[i].w; //必须要加判断,num[j]不能超过inf
}
else {
for(int j = ope[i].l; j <= ope[i].r; ++j)
if(num[j] > ope[i].w) num[j] = ope[i].w;
}
}
for(int i = 1; i <= n; ++i) ans[i] = num[i];
int flag = 0;
for(int i = 0; i < m; ++i){
if(ope[i].op == 1){
for(int j = ope[i].l; j <= ope[i].r; ++j)
num[j] += ope[i].w;
}
else{
int curmax = -inf;
for(int j = ope[i].l; j <= ope[i].r; ++j)
curmax = max(curmax, num[j]);
if(curmax != ope[i].w){
flag = 1;
break;
}
}
}
if(flag) cout << "NO" << endl;
else{
cout << "YES" << endl;
for(int i = 1; i <= n; ++i)
cout << ans[i] << ' ';
cout << endl;
}
}
return 0;
}