BOJ 19693, Singapore NOI 2018 Safety
- ๋์ด๋ : Diamond 4
- ์ถ์ฒ : Singapore National Olympiad in Informatics, 2018 - 5๋ฒ
Thinking ํํธ๊ฐ ๋๋ ํ์๋ ์ด๋ป๊ฒ ๊ตฌํํ ์ง ์ ๋ง ๋ง์ ๊ณ ๋ฏผ์ ํ๊ณ , ๊ฒฐ๊ตญ ๊ตฌํ์ ์ฑ๊ณตํ์ง ๋ชปํด์ ๋ค๋ฅธ ์ฌ๋ ๊ตฌํ์ ์ฐธ๊ณ ํ๋ค. ๊ตฌํ ํธ๋ฆญ์ด ์๋นํ ๋ฐฐ์ธ์ ์ด ๋ง์๋ค.
ํ์ด
์ฃผ์ด์ง ๋ฌธ์ ๋ฅผ formulateํ๋ฉด, ๊ฐ element๊ฐ $S$ ์ดํ์ธ $N$๊ฐ์ง๋ฆฌ sequence์ increment ๋๋ decrement ํ๋ ์ฐ์ฐ์ ์ต์ํ์ผ๋ก ํด์, $\abs{a_i - a_{i-1}} \leq H$ ๊ฐ ๋๊ฒ ํ๊ณ ์ ํ ๋ ํ์ํ ์ต์ ํ์๋ฅผ ๊ตฌํ๋ ๋ฌธ์ ์ด๋ค.
๋จผ์ , ๋ต์ด ๋๋ sequence๋ฅผ $b_i$ ๋ผ๊ณ ํ๊ณ , $a_i$๋ฅผ $b_i$๋ก ๋ฐ๊พธ๋ ค๊ณ ํ๋ค๊ณ ํ์. ์ด๋, ๊ด์ฐฐํ ์ ์๋ ์ฌ์ค์, ํ์ฌ ๊ฐ์ฅ ํฐ element๋ณด๋ค $b_i$๊ฐ ๋ ์ปค์ ธ์ผ ํ ์ด์ ๊ฐ ์ ํ ์๋ค. (๊ฑฐ์ ์๋ช ํ๋ค)
Subtask 1, 2, 5 (+13์ )
$b_i$ ๋ $S$ ์ดํ์ด๋ฏ๋ก, ๋ค์๊ณผ ๊ฐ์ DP ํ ์ด๋ธ์ ์๊ฐํ ์ ์๋ค.
dp[i][j] : a[1]...a[i] ๊น์ง๋ง ๊ณ ๋ คํ๊ณ , b[i] = j๊ฐ ๋๋๋ก ํ ๋ ํ์ํ ์ต์ ํ์
์ด DP ํ
์ด๋ธ์ ์๊ฐํด ๋ณด๋ฉด, dp[i][j]
๋ฅผ ๊ณ์ฐํ๊ณ ์ ํ ๋, dp[i-1][*]
์ ์ ๋ณด๋ง ์์ผ๋ฉด ๋๋ค. ๊ตฌ์ฒด์ ์ผ๋ก, ์์ด์ $i-1$๋ฒ์งธ๊ฐ $k$์ผ ๋, $i$๋ฒ์งธ๊ฐ $j$๊ฐ ๋ ์ ์๋ ๊ฐ๋ฅ์ฑ์ด ์๋์ง๋ฅผ ๋จผ์ ์์์ผ ํ๊ณ , ๋ง์ฝ ๊ฐ๋ฅํ๋ค๋ฉด ํ์ฌ $a_i$๋ฅผ $j$๊น์ง ๋ฐ์ด์ผ ํ๋ค. ์ฆ, ๋ค์๊ณผ ๊ฐ์ transition์ ์๊ฐํ ์ ์๋ค.
๋น์ฐํ, $j-h$ ๋ $j+h$ ๋ฒ์๊ฐ $0$์ด๋ $S$๋ฅผ ๋์ง ์๋๋ก ํด์ผ ํ ๊ฒ์ด๋ค. ์ด DP ํ ์ด๋ธ์ ๊ทธ๋ฅ ๊ทธ๋๋ก ๊ณ์ฐํ๋ฉด $O(NSH)$ ์๊ฐ์ด ๊ฑธ๋ฆฌ๊ณ , $O(NS)$์นธ ํ ์ด๋ธ์ด ํ์ํ๋ค. ๋ชจ๋ ๊ฐ๊ฐ์ ์์๊ฐ ์๊ฒ control๋์ด ์๋ 1, 2, 5๋ฒ ์๋ธํ์คํฌ๋ฅผ ์ด DP๋ก ํด๊ฒฐ ๊ฐ๋ฅํ๋ค.
Subtask 4 (+5์ )
$H = 0$์ผ ๋๋, ๊ฒฐ๊ตญ $a_i$๋ค์ ๋ชจ๋ ๋๊ฐ์ด ๋ง์ถฐ์ผ ํ๋ฉฐ, $a_i$ ๋ค ์ค ์ค๊ฐ๊ฐ์ด ๋ต์์ด ์ ์๋ ค์ ธ ์๋ค.
Full solution
์ DP๋ฅผ ๊ฐ์ ํ๊ณ ์ ํ๋ค. ์ด๋, dp(i, x)
๋ฅผ $x$์ ๋ํ ํจ์ $f_i (x)$์ฒ๋ผ ์๊ฐํ์. ๊ทธ๋ฆฌ๊ณ ์ฒซ๋ฒ์งธ min ํํธ์, ๋๋ฒ์งธ abs๋ฅผ ๋ํ๋ ํํธ๋ฅผ ๋๋๋ ค๊ณ ํ๋ค.
- min์ ํ๋ ํํธ๋, ํจ์์์ ์๊ฐํ๋ฉด, $f_i(x)$์ ๊ฐ์ ๊ทธ ์ฃผ๋ณ $H$๋งํผ์ ๊ตฌ๊ฐ์ ์ต์๊ฐ์ผ๋ก ๋์ฒดํ๋ ์ฐ์ฐ์ด๋ค.
- abs๋ ๊ทธ๋๋ก, $f_i$์ ์ง์ $\abs{a_i - x}$ ๊ฐ ๋ํด์ง๋ ์ฐ์ฐ์ด๋ค.
๊ฒฐ๊ตญ ์ด ๋ ์ฐ์ฐ์ ๊ต๋๋ก ์ํํ๋ ๊ฒ์ด๋ฏ๋ก, $\abs{a - x}$ ํจ์๊ฐ ์ฌ๋ฌ ๊ฐ ๋ํด์ง๊ณ , ๊ตฌ๊ฐ minimum์ ๊ณ์ ์ทจํ๋ ๊ฒ์ด๋ค. ์ด๋, abs ํจ์์ ํฉ์ด ํญ์ convexํจ์ ์ฃผ๋ชฉํ์. ๋ํ, ํจ์์์ ๊ธฐ์ธ๊ธฐ๊ฐ ๋ฐ๋๋ ์ง์ ์ด $2n$๊ฐ ๋ฐ์ ์์์ ์ ์ ์๋ค.
abs๊ฐ ์ฌ๋ฌ๊ฐ ๋ํด์ง ํจ์์ ๊ตฌ๊ฐ minimum์ ์ทจํ๋ ๊ฒ์, ํจ์์ ๊ธฐ์ธ๊ธฐ ๋ถํธ๊ฐ ๋ฐ๋๋ ๋ถ๋ถ์ ๊ธฐ์ค์ผ๋ก, ์์ชฝ์ ๊ธฐ์ธ๊ธฐ๊ฐ ๋ฐ๋๋ ์ ์ ์ผ์ชฝ ์ ์ ๋ ์ผ์ชฝ์ผ๋ก, ์ค๋ฅธ์ชฝ ์ ์ ๋ ์ค๋ฅธ์ชฝ์ผ๋ก ๋ฏธ๋ ํจ๊ณผ๊ฐ ๋๋ค.
์ฌ์ง์ ๊ณต์ ํ์ด์์ ๊ฐ์ ธ์๋ค. ์ด๊ฑธ ๊ทธ๋ฆด ์์ ์ด ์์ด์โฆ :(
๋ฐ๋ผ์, ์ ์ ํ ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ด์ฉํ์ฌ, ํจ์์ ๊ธฐ์ธ๊ธฐ๊ฐ ๋ฐ๋๋ ์ ๋ค์ ๋ชจ๋ ๊ธฐ๋กํ๊ณ , ์ด๋ค์ ๋ฏธ๋ ์ฐ์ฐ๊ณผ ์ถ๊ฐํ๋ ์ฐ์ฐ์ ์ ํด์ค ์ ์์ผ๋ฉด ๋๋ค.
๊ตฌํ
์ฌ์ค ์ฒ์์๋ ์ ๊ธฐ๋ค๊ฐ Dynamic Lazy Segment Tree ๊ฐ์๊ฑธ ์ ๋ฐ์์ ์ด๋ป๊ฒ ํด๋ณด๋ ค๊ณ ์๊ฐํ์๋๋ฐ, ๋ช์๊ฐ๋์ ๊ณ ์ํ๋ค๊ฐ ๊ฒฐ๊ตญ ์คํจํ๋ค. ๊ณต์ ์๋ฃจ์ ์ (๊ทธ๋ฆฌ๊ณ ๋ด๊ฐ ๋ณธ ๊ฑฐ์ ๋ชจ๋ ํ์ด๋) ์๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌํํ๋ค.
๊ธฐ์ธ๊ธฐ๊ฐ ๋ฐ๋๋ ์ ๋ค์ ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ง๊ณ ์์. ๊ตฌํ์ ํธ์๋ฅผ ์ํด, ์ด ๋ฆฌ์คํธ๋ ๋ฐ๋ณต์ ํ์ฉํ๋ค. ์ฆ, $(-\infty, 1)$ ์์์ ๊ธฐ์ธ๊ธฐ๊ฐ -3์ด๊ณ , $(1, 3)$ ์์์ ๊ธฐ์ธ๊ธฐ๊ฐ -1, $(3, 5)$์์์ ๊ธฐ์ธ๊ธฐ๊ฐ 0, $(5, 8)$์์์ ๊ธฐ์ธ๊ธฐ๊ฐ 1์ด๋ผ๋ฉด, ์ด๋ฅผ ์ ์ฅํ ๋ 1, 1, 3, 5, 8 ๊ณผ ๊ฐ์ด ์ ์ฅํ๋ค. 1์ด ๋ ๋ฒ ๋์ค๋ ๊ฒ์ ๊ธฐ์ธ๊ธฐ๊ฐ ๋ ๋ฒ ๋ณํจ์ ์ง์ ํ์ํ๋ ๊ฒ์ด๋ค. ์ด๋ ๊ฒ ํด๋, ์์ชฝ์ ๊ธฐ์ธ๊ธฐ๊ฐ $-n$๋ถํฐ $n$๊น์ง์ด๊ธฐ ๋๋ฌธ์, $2n$๊ฐ ์ ๋์ ์ ๋ง ์์ผ๋ฉด ๋๋ค.
์ด๋, ๊ธฐ์ธ๊ธฐ $0$์ ๊ธฐ์ค์ผ๋ก, ์์ชฝ์ multiset ๊ฐ์ ์๋ฃ๊ตฌ์กฐ๋ก ๊ด๋ฆฌํ๋ค. ๋์ค์ ์ด ์ ๋ค ์ ์ฒด๋ฅผ ๋ค๊ณ ์์ชฝ์ผ๋ก ๋ฐ์ด์ผ ํ๋๋ฐ, ์ง์ ๋ฏธ๋ ๋์ offset์ ๊ธฐ๋กํ ๊ฒ์ด๋ค.
- min์ฐ์ฐ์ ์ด์ offset์ ๋ฐ๊ฟ์ค์ผ๋ก์จ $O(1)$์ ํ ์ ์๋ค.
- abs ๋ฅผ ๋ํ๋ ์ฐ์ฐ์, ๋ค์๊ณผ ๊ฐ์ด ์ํํ๋ค. ๋จผ์ $\abs{a_i - x}$๋ฅผ ๋ํ๋ฉด $a_i$๋ฅผ ๊ธฐ์ค์ผ๋ก ์ผ์ชฝ์๋ ๊ธฐ์ธ๊ธฐ๊ฐ -1 ๋ํด์ง๊ณ , ์ค๋ฅธ์ชฝ์๋ ๊ธฐ์ธ๊ธฐ๊ฐ 1 ๋ํด์ง๋ค๋ ์ฌ์ค์ ๊ด์ฐฐํ์. ๋ฐ๋ผ์, $a_i$๋ฅผ ๋ ๋ฒ ๋ฃ์ด ์ฃผ๋ฉด, ์๋ฌด ๋ฌธ์ ๊ฐ ์๊ฒ ๋๋ค.
- ์ด๋, ์์ ์์ชฝ์ multiset์ผ๋ก ๊ฐ๊ฐ ๊ด๋ฆฌํ๊ธฐ๋ก ํ์ผ๋ฏ๋ก, $a_i$์ ์์น๋ฅผ ๋ณด๊ณ ์ด๋์ ๋ฃ์ด ์ฃผ์ด์ผ ํ๋์ง ์ฐพ์์ผ ํ๋ค.
- ๋ง์ฝ ์ผ์ชฝ multiset์ ๋ค์ด๊ฐ๋ ๊ฒฝ์ฐ, ์ผ์ชฝ multiset์ ๋งจ ๋ ๊ฐ (๊ธฐ์ธ๊ธฐ๊ฐ ์๋ -1์์ 0์ผ๋ก ๋์ด๊ฐ๋ ๋ถ๋ถ)์ด ์ด์ 0์์ 1๋ก ๋์ด๊ฐ๋ ๋ถ๋ถ์ด ๋๋ค. ๋ฐ๋ผ์, ์ด๋ฅผ ์ผ์ชฝ์์ ๋นผ์ ์ค๋ฅธ์ชฝ์ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค. ๊ทธ ๋ฐ๋์ด๋ฉด ๋น์ฐํ ๊ฐ์ ๋ฐฉํฅ์ด ๋ฐ๋๋ก ๊ฐ๋ค.
- ๋ง์ง๋ง์ ๊ธฐ์ธ๊ธฐ 0์ ํด๋นํ๋ $x$๋ฅผ ๋ณด๊ณ ๋ตํ๋ฉด ๋๋ค. ํจ์๊ฐ์ ์ค์ ๊ณ์ฐ๋ ๋ณ๋ก ์ด๋ ต์ง ์๋ค.
๋ง๋ก ์ค๋ช ํ๊ธฐ ์ ๋ง ๋์ฐํ์ง๋ง, ์ฝ๋๋ ๊ทธ๋ ๊ฒ ์ฌ๊ฐํ๊ฒ ์ด๋ ต์ง ์๋ค. ์ด๊ฑธ ๊ธฐ์ธ๊ธฐ๊ฐ์ ๊ทธ๋๋ก multiset๊ฐ์๊ฑธ๋ก ๊ด๋ฆฌํ๋ค๋ ๋ฐ์์ด ๊ฐ์ฅ ์ด๋ ค์ด ๊ฒ ๊ฐ๋ค.
์ฝ๋
#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#define ll long long
#define eps 1e-7
#define all(x) ((x).begin()),((x).end())
#define usecppio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
#define int ll
using pii = pair<int, int>;
int INF = 1e15;
const int MN = 202020;
const int LEND = -1e17;
const int REND = 1e17;
int N, H;
int s[MN];
struct mset {
multiset<int> st;
int offset;
int small() {
return *st.begin() + offset;
}
int large() {
return *st.rbegin() + offset;
}
void del(int e) {
if (e == LEND)
st.erase(st.begin());
else if (e == REND)
st.erase(prev(st.end()));
else
st.erase(st.lower_bound(e));
}
void ins(int e){
st.insert(e);
}
} l, r;
int32_t main()
{
usecppio
cin >> N >> H;
int MH = 0;
for (int i = 1; i <= N; i++)
{
cin >> s[i];
MH = max(MH, s[i]);
}
l.ins(s[1]);
r.ins(s[1]);
int ans = 0;
for (int i = 2; i <= N; i++)
{
l.offset -= H;
r.offset += H;
int lf = l.large();
int rf = r.small();
if (s[i] < lf)
{
l.ins(s[i] - l.offset);
l.ins(s[i] - l.offset);
l.del(REND);
r.ins(lf - r.offset);
ans += abs(lf - s[i]);
}
else if (s[i] > rf)
{
r.ins(s[i] - r.offset);
r.ins(s[i] - r.offset);
r.del(LEND);
l.ins(rf - l.offset);
ans += abs(rf - s[i]);
}
else
{
l.ins(s[i] - l.offset);
r.ins(s[i] - r.offset);
}
}
cout << ans << '\n';
}