题目链接:http://codeforces.com/group/NVaJtLaLjS/contest/238651/problem/H
题面:
题意:给你一个操作序列,问是否存在一个数组经过操作后能满足。
思路:先将数组的值全部赋值为1e9然后逆着推,遇到操作1,就减,遇到操作2就将区间中大于v的数组更改为v。
注意的地方:操作一中要注意加个num[i] != inf(1e9)因为减的数有可能是负数,而生成的数组要求是-1e9到1e9。
代码:
#include<bits/stdc++.h>
using namespace std;
int num[5500];
int ans[5500];
struct noode{
int type;
int l;
int r;
int v;
}ope[5500];
const int inf = 1e9;
int main(){
int n,m;
cin >> n >> m;
for(int i = 0;i < 5500; i++){
num[i] = inf;
}
for(int i = 0;i < m; i++){
scanf("%d%d%d%d",&ope[i].type,&ope[i].l,&ope[i].r,&ope[i].v);
}
for(int i = m-1;i >= 0; i--){
if(ope[i].type == 2){
for(int j = ope[i].l;j <= ope[i].r; j++){
num[j] = num[j] > ope[i].v ? ope[i].v:num[j];
}
}
else{
for(int j = ope[i].l;j <= ope[i].r; j++){
if(num[j] != inf)num[j] -= ope[i].v;
}
}
}
for(int i = 0;i < m; i++){
cout<<num[i]<<" ";
}
cout<<endl;
for(int i = 1;i <= n; i++)ans[i] = num[i];
for(int i = 0;i < m; i++){
if(ope[i].type == 2){
int res = num[ope[i].l];
for(int j = ope[i].l;j <= ope[i].r; j++){
res = max(res,num[j]);
}
if(res != ope[i].v){
printf("NO");
return 0;
}
}
else{
for(int j = ope[i].l;j <= ope[i].r; j++){
num[j] += ope[i].v;
}
}
}
printf("YES\n");
for(int i = 1;i <= n; i++){
printf("%d ",ans[i]);
}
return 0;
}