Levko and Array Recovery

题面链接:传送门

题意描述:

       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;
}

猜你喜欢

转载自blog.csdn.net/weixin_41100093/article/details/87517579
今日推荐