티스토리 뷰
Link
Problem
The JOI plain is a wide plain spreading from west to east. We can consider the JOI plain as a number line. A spot on the JOI plain is denoted by a coordinate. The positive direction of the number line corresponds to the east direction. Now winter comes in the JOI plain. There are N snowballs on it, numbered from 1 to N from the west to the east. In the beginning, the coordinate of the snowball i (1 ≤ i ≤ N) is an integer Xi.
Strong wind blows in the JOI plain in winter. You have observation data of wind for Q days. On the j-th day (1 ≤ j ≤ Q), the wind is described by an integer Wj. If Wj is negative, then the wind blows to the west direction. If Wj is not negative, then the wind blows to the east direction. The strength of the wind is |Wj|.
When wind blows, a snowball is moved to the same direction as the wind, and its length of move is equal to the strength of the wind. In other words, if there is a snowball in the coordinate x in the beginning of the j-th day (1 ≤ j ≤ Q), then the snowball is moved from the coordinate x to the coordinate x + Wj. At the end of the j-th day, the coordinate of the snowball becomes x + Wj. Note that, in each day, the snowballs are moved at the same time, and their speeds are the same.
Initially, the JOI plain is covered with snow. If a snowball is moved on an interval covered with snow, then the snowball accumulates the snow, the weight of the snowball is increased, and the snow on the interval disappears. In other words, for an integer a, assume that the interval from
Initially, the weight of every snowball is 0. It did not snow on the Q days of observation data.
You want to know the weight of each snowball at the end of the Q-th day.
Write a program which, given the initial position of each snowball and observation data of wind for Q days, calculates the weight of each snowball at the end of the Q-th day
Input
Read the following data from the standard input. Given values are all integers.
1≤N≤200000 1≤Q≤200000 |Xi|≤1012 (1≤i≤N) Xi<Xi+1 (1≤i≤N−1) |Wj|≤1012 (1≤j≤Q)
N Q
X₁ · · · XN
W₁
.
.
.
WQ
Subtask
Index Score Restriction
1 | 33 | N ≤ 2 000, Q ≤ 2 000. |
2 | 67 | No additional constraints. |
Subtask 1(O(NQ) )
문제의 예제를 직접 손으로 돌려보고, 몇 가지 생각을 해보면 관찰을 몇가지 할 수 있다.
Observation 1
Claim)
Proof) 만약
이때, 모든 눈덩이들이 바람이 불 때마다 움직이므로
따라서
이때,
Observation 2
바람에 의해서 오른쪽으로 움직인 정도를
만약,
만일 바람
Observation 2에 의해 총
한 번의 바람 당
Subtask 2(O(Q+NlgN) )
일단,
따라서
이를 이용하면, 몇몇 구간에 대해서는 볼 필요가 없음을 알 수 있는데,
- 이미 구간의 길이가
보다 작아서 이후의 바람이 불어오는 것과 관련 없이 구간 내의 weight가l+r 인 경우0 - 바람이 불어도
여서 단순히 더해주기만 하는 경우l+r<T[i]
즉, 우리가 문제에서 특수하게 다루어야 할 부분은 바람
구간이 짧을수록 weight가 빠르게 사라지므로 구간의 길이를 기준으로 정렬해준 이후에, 매 바람이 불 때마다 구간의 길이와
마지막에 구간이 너무 길어서 아무리 바람이 불어도 겹치지 않을 수 있으니,
정렬을 하는데
따라서 총 시간 복잡도는
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, int> pli;
#define MAX 2000000000005
#define x first
#define y second
int p;
ll l, r, v;
vector<pli> co;
ll a[200006], ans[200006];
int main() {
int n, q;
scanf("%d %d", &n, &q);
a[0] = -MAX, a[n+1] = MAX;
for(int i = 1; i<=n;i++) scanf("%lld", &a[i]), co.push_back({a[i+1]-a[i], i}); // range
sort(co.begin(), co.end());
while(q--) {
ll t;
scanf("%lld", &t);
if(t>=0) {
// if t > 0, wind is east direction
// That means, snowball goes to right, so update right value
// If |now wind value| > |before wind value|, update. else, not update => max operation
v += t;
r = max(r, v);
// if l + r > (range) + wind east, so Left snowball will be moved
// Right snowball's weight: L, Left snowball's weight: (range)-L
// After that, doesn't remain weight => skip
while(p<=n && co[p].x <= l+r) {
ans[co[p].y+1] += l;
ans[co[p].y] += co[p].x - l;
++p;
}
}
else {
// if t < 0, wind is west direction
// That means, snowball goes to left, so update left value
// If |now wind value| > |before wind value|, update. else, not update => max operation
v += t;
l = max(l, -v);
while(p<=n && co[p].x <= l+r) {
ans[co[p].y] += r;
ans[co[p].y+1] += co[p].x - r;
++p;
}
}
}
for(int i=1;i<=n;i++) printf("%d\n", co[p].y);
while(p<=n) {
ans[co[p].y] += r;
ans[co[p].y + 1] += l;
++p;
}
for(int i=1; i<=n;i++) printf("%lld\n", ans[i]);
return 0;
}
|
cs |
'백준' 카테고리의 다른 글
[BOJ 20982] 安全点検 (Safety Inspection) (0) | 2022.07.30 |
---|---|
[BOJ 16993] 연속합과 쿼리 (0) | 2022.07.23 |
[BOJ 17411] 가장 긴 증가하는 부분수열 6 (0) | 2022.07.21 |
[BOJ 2873] 롤러코스터 (0) | 2022.07.19 |
[BOJ 2843] 마블 (0) | 2022.07.18 |
- Total
- Today
- Yesterday
- 세그먼트 트리
- 선형대수학
- 백준 17411
- joi
- 해석학 Ch5
- 해석학
- 미분
- PMA 연습문제
- 수(상)
- Differentation
- mathematics
- Trace trick
- cs231n assignment1
- Deep learning
- JOI 2021
- 해석학II
- PMA
- 백준
- icpc.me/17411
- Backprop
- 수학
- LInear SVM
- Machine Learning
- PMA Ch5
- Trace tirck
- 17411
- 해석학 Chapter 5
- 연습문제
- Derivate
- 로피탈
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |