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
output
input
output
题意:
给定一个序列,然后对其进行两种操作
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;
}
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;
}
相关文章推荐
- CodeForces 360A - Levko and Array Recovery (思维)
- CodeForces 360A - Levko and Array Recovery (模拟)
- CodeForces 360A - Levko and Array Recovery 给出操作求原始数列
- CodeForces - 361C A - Levko and Array Recovery 思维
- Codeforces Round #210 (Div. 2) C. Levko and Array Recovery
- A. Levko and Array Recovery----思维题
- CF-Codeforces Round #210 (Div. 1)-A-Levko and Array Recovery
- CodeForces 360 B.Levko and Array(二分+dp)
- Codeforces 361C - Levko and Array Recovery(贪心)
- Codeforces Round #210 (Div. 1) B. Levko and Array(dp 思维)
- Codeforces Round #253 (Div. 2) E. Artem and Array (思维)
- Codeforces Round #390(Div. 2)A. Lesha and array splitting【思维】
- Codeforces Round #210 (Div. 1)——Levko and Array
- Codeforces Round #419 (Div. 2)-贪心&思维-C. Karen and Game
- 【codeforces 718 C&D】C. Sasha and Array&D. Andrew and Chemistry
- Codeforces Round #378 (Div. 2) && codeforces 733D(思维枚举)
- Codeforces 718C Sasha and Array(线段树维护矩阵)
- codeforces 355(Div 2)C. Vanya and Label(思维,预处理)
- codeforces 251 div2 C. Devu and Partitioning of the Array 模拟
- Codeforces Round #373 (Div. 2) E. Sasha and Array 线段树维护矩阵