您的位置:首页 > 运维架构

Codeforces Round #210 (Div. 2) C. Levko and Array Recovery && Codeforces 360 A 详解(思维+维护理论值)

2017-02-23 14:07 736 查看
C. Levko and Array Recovery

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

Levko loves array a1, a2, ...
, an, consisting of integers, very much. That is why Levko is playing with array a,
performing all sorts of operations with it. Each operation Levko performs is of one of two types:

Increase all elements from li to ri by di.
In other words, perform assignments aj = aj + di for
all j that meet the inequation li ≤ j ≤ ri.

Find the maximum of elements from li to ri.
That is, calculate the value 

.

Sadly, Levko has recently lost his array. Fortunately, Levko has records of all operations he has performed on array a. Help Levko,
given the operation records, find at least one suitable array. The results of all operations for the given array must coincide with the record results. Levko clearly remembers that all numbers in his array didn't exceed 109 in
their absolute value, so he asks you to find such an array.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 5000)
— the size of the array and the number of operations in Levko's records, correspondingly.

Next m lines describe the operations, the i-th
line describes the i-th operation. The first integer in the i-th
line is integer ti (1 ≤ ti ≤ 2)
that describes the operation type. If ti = 1,
then it is followed by three integers li, ri and di (1 ≤ li ≤ ri ≤ n,  - 104 ≤ di ≤ 104)
— the description of the operation of the first type. If ti = 2,
then it is followed by three integers li, ri and mi (1 ≤ li ≤ ri ≤ n, - 5·107 ≤ mi ≤ 5·107)
— the description of the operation of the second type.

The operations are given in the order Levko performed them on his array.

Output

In the first line print "YES" (without the quotes), if the solution exists and "NO"
(without the quotes) otherwise.

If the solution exists, then on the second line print n integers a1, a2, ...
, an (|ai| ≤ 109) —
the recovered array.

Examples

input
4 5
1 2 3 1
2 1 2 8
2 3 4 7
1 1 3 3
2 3 4 8


output
YES
4 7 4 7


input
4 5
1 2 3 1
2 1 2 8
2 3 4 7
1 1 3 3
2 3 4 13


output
NO


题意:
给定一个序列,然后对其进行两种操作
1   L R W   代表从 a[L ] 到a[R] 全部加上W
2   L R W  代表从  a[L] 到 a[R] 中最大值为 W
问是否存在一个序列满足上序操作  , 操作数量小于5000

思路: 这种题,因为不知道初始值是什么,那就先倒着找,倒着遇到的操作2,把这个区间全部更新为最大值,如果某些数又有新的最大值,那就取最小的,如果这个数已经更新过了,遇到1就直接减掉那个数,得到当前这个位置的理论最大值,否则不用减,因为他还可以为任意值,没有max的限制,循环完最后得到一个序列,这序列是由条件倒着推出来的每个位置的理论值,那么如果正着也符合这个理论值,就符合,否则就是不行,其实先正着再倒着也可以,都是先推出理论值,再反着一遍检验理论值对不对

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 5e3 + 5;
const int INF = 1e9;
int l[maxn], r[maxn], cmd[maxn], val[maxn], limit[maxn], temp[maxn];
int main()
{
int n, m;
while(~scanf("%d%d", &n, &m))
{
for(int i = 1; i <= n; i++)
limit[i] = INF;
for(int i = 1; i <= m; i++)
scanf("%d%d%d%d", &cmd[i], &l[i], &r[i], &val[i]);
for(int i = m; i >= 1; i--)
{
if(cmd[i] == 1)
{
for(int j = l[i]; j <= r[i]; j++)
if(limit[j] != INF)
{
limit[j] -= val[i];
}
}
else
{
for(int j = l[i]; j <= r[i]; j++)
{
limit[j] = min(limit[j], val[i]);
}
}
}
for(int i = 1; i <= n; i++) temp[i] = limit[i];
int flag = 0;
for(int i = 1; i <= m; i++) //检验理论值对不对
{
if(cmd[i] == 1)
{
for(int j = l[i]; j <= r[i]; j++)
temp[j] += val[i];
}
else
{
int max1 = -INF;
for(int j = l[i]; j <= r[i]; j++)
{
max1 = max(max1, temp[j]);
}
if(max1 != val[i])
{
flag = 1;
break;
}
}
}
if(!flag)
{
printf("YES\n");
for(int i = 1; i <= n; i++)
printf("%d ", limit[i]);
printf("\n");
}
else
printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: