<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>옥토끼 블로그</title>
    <link>https://moonrabbit2.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 6 Aug 2026 21:28:06 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>moonrabbit2</managingEditor>
    <item>
      <title>BOJ 25384 니은숲 예술가</title>
      <link>https://moonrabbit2.tistory.com/8</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;정해에 소개된 방식과 다른 접근법을 이용한 DP를 사용하면, 정해와 마찬가지로 $O(N^2)$ DP 풀이를 얻을 수 있고, 이것이 UCPC 당시 우리 팀의 풀이였다. 이 글에서는 해당 풀이와, 해당 풀이를 개선해 $O(N)$에 해결하는 법을 소개한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 방향을 두 조각으로 분리하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크기 1의 조각부터, 크기 $N$의 조각까지를 순서대로 붙여나가는 것을 생각하자. 새로 붙인 크기 $N$의 조각과 만나는 조각들은 새로 붙인 조각의 방향에 따라 기존 조형물의 윗쪽 또는 아래쪽에 아직 일부분이 남아있는 조각들과, 왼쪽 또는 오른쪽에 일부분이 남아있는 조각들이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 조각을 붙인 4가지 방향을, 상하 방향 2가지와, 좌우 방향 2가지 각각의 정보로 분리할 수 있다. 이렇게 분리할 경우 좋은 점은 윗쪽 또는 아래쪽에 일부분이 남아있어 만나는 경우는 오직 상하 방향에, 왼쪽 또는 오른쪽에 일부분이 남아있어 만나는 경우는 오직 좌우 방향에만 영향을 받는다는 점이다. 정확한 분석은 2문단에서 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 사실을 알았다면, 문제를 상하 방향과 좌우 방향에 대해 독립적으로 해결할 수 있다. 답은 가능한 상하 방향 배열의 개수와 좌우 방향 배열의 개수의 곱이 된다. 그런데, 두 문제는 방향만 다를 뿐 완전히 동일한 문제이기에, 좌우 방향 문제만 해결한 후, 좌우 방향 배열의 개수의 제곱이 답이 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. $O(N^2)$ DP&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 좌우 방향으로 만나는 조각들에 대한 정확한 분석이 필요하다. 일반성을 잃지 않고 $N$번 조각을 오른쪽에 붙였다고 하자. 또한, $j$번 조각과 $i$번 조각이 서로 다른 방향으로 붙여진 최소 $j$를 $L_i$로 정의하자. $L_N+2 \le i \le N$인 $i$에 대해, $i$번 조각은 바로 왼쪽의 $i-1$번 조각과만 좌우 방향으로 만난다. 하지만, $L_N + 1$번 조각은 여러 조각들과 좌우 방향으로 만날 수 있는데, 해당 조각들은 $L_N + 1$번 조각 이전에 마지막으로 오른쪽 방향으로 조각을 붙인 후, 왼쪽 방향으로 조각들을 붙이면서 오른쪽에 하나씩 자리를 차지하게 되는 조각들이다. 즉, $L_{L_N}$번 조각부터 $L_N$번 조각까지가 $L_N + 1$번 조각과 만나게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 사실을 이용한 점화식을 설계하자. $D_{i, j}$를 $i$번 조각까지 붙였을 때, $L_i = j$인 경우의 수로 정의하자. $i - 1$번 조각과 $i$번 조각의 방향이 같다면 $L_i = L_{i-1}$이고, 그렇지 않다면 $L_i = i - 1$이다. 이를 이용해, DP 전이를 두 가지로 나눌 수 있다. 단, 1 이상 $N - 1$ 이하의 모든 $i$에 대해 $C_i \neq C_{i+1}$을 가정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$i - 1$번 조각과 $i$번 조각의 방향이 같은 경우, $i$번 조각은 $i - 1$번 조각과만 만난다. $C_i \neq C_{i-1}$이므로, 전이는 $1 \le j &amp;lt; i - 1$인 모든 $j$에 대해 $D_{i-1, j} \rightarrow D_{i, j}$이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$i - 1$번 조각과 $i$번 조각의 방향이 다른 경우, $i$번 조각은 $L_{i-1}$번 조각부터 $i-1$번 조각까지와 만난다. 전이는 $j$번 조각부터 $i -1$번 조각 사이에 $i$번 조각과 $C$값이 같은 조각이 없는 모든 $j$에 대해 $D_{i-1, j} \rightarrow D_{i, i-1}$이다. $S_i$를 $j$번 조각부터 $i-1$번 조각 사이에 $i$번 조각과 $C$값이 같은 조각이 없는 최소 $j$라 하면, $\sum_{j=S_i}^{i-1} D_{i-1, j} \rightarrow D_{i, i-1}$로도 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 조각의 경우 방향을 정의하기도 애매하고 여러모로 초기값이 문제가 되는데, 회전을 같은 경우로 처리하지 않는다는 점을 이용해, 1번 조각과 2번 조각의 서로 방향이 다르다고 설정해주자. $D_{2, 1} = 1$로 설정하고, 3 이상의 $i$에 대해서 직접 점화식을 계산하면 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. $O(N \log N)$으로 개선하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 $D_{i,j}$는 $D_{i-1,j}$와 같고, 다른 것은 오직 $D_{i, i-1}$이다. 또한, $D_{i, i-1}$은 $D_{i-1}$ 배열 상의 구간 합을 이용해 구할 수 있다. 즉, 현재의 $D$배열을 세그먼트 트리 또는 펜윅 트리를 이용해 관리한다 생각할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업데이트는 결과적으로는 굉장히 간단하다: $\sum_{j=S_i}^{i-1} D_j$을 세그먼트 트리 쿼리를 이용해 $O(\log N)$에 구한 후, $D_{i-1}$에 해당 값을 더해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;답은 모든 업데이트 이후 $\sum_{j=1}^{N-1} D_j$이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드: &lt;a href=&quot;http://boj.kr/787245c89843420ab5762b8b48fc7a67&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://boj.kr/787245c89843420ab5762b8b48fc7a67&lt;/a&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4. $O(N)$으로 개선하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세그먼트 트리 없이 부분합을 이용하는 것이 가능함을 어렵지 않게 관찰할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드: &lt;a href=&quot;http://boj.kr/e2ed901f35844076840f6db6221f66bc&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://boj.kr/e2ed901f35844076840f6db6221f66bc&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>PS</category>
      <author>moonrabbit2</author>
      <guid isPermaLink="true">https://moonrabbit2.tistory.com/8</guid>
      <comments>https://moonrabbit2.tistory.com/8#entry8comment</comments>
      <pubDate>Thu, 18 Aug 2022 02:19:18 +0900</pubDate>
    </item>
    <item>
      <title>2022 국제정보올림피아드 선발고사 풀이</title>
      <link>https://moonrabbit2.tistory.com/6</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;서브태스크의 경우 제가 풀이를 알면서 만점으로 가는 길에 있는 경우에만 설명합니다. 풀이들은 제가 해결한 방식이고, 다른 풀이들이 있을 수 있습니다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;1 - 1. 진화&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (33점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;각 쿼리마다, 해당 서브트리에 대한 DP로 문제를 해결한다. 각 정점 $u$를 기준으로 해당 정점을 LCA로 가지는 경로들을 생각해보자. 이미 $u$의 서브트리 내에서 $u$에서 자식으로 향하는 간선들을 제외하면 모두 분류가 완료되었을 경우, $u$에서 자식으로 향하는 간선들 중 주요 진화로 정할 간선은 어떻게 정할까?&lt;br /&gt;&lt;br /&gt;자식 쌍 $c1,c2$에 대해, $c1$과 $c2$를 지나며 $u$를 LCA로 가지는 경로들만 고려했을 때 부가 진화의 최댓값은 $d_{c1}+add_{c1}+d_{c2}+add_{c2}$이다. 여기서 $d_c$는 $c$의 서브트리에서 가장 깊은(가장 많은 부가 진화를 지나는) 정점의 깊이이고, $add_c$는 $c$로 향하는 진화가 주요 진화이면 0, 부가 진화이면 1이다.&lt;br /&gt;&lt;br /&gt;동시에, $u$의 조상들에서의 처리를 위해서는 $d_u$를 구해야 한다. $d_u$는 $d_c + add_c$의 최댓값이다.&lt;br /&gt;&lt;br /&gt;두 값들을 동시에 최소화하는 방법은 $d_c$값이 가장 큰 자식 $c$로 향하는 진화를 주요 진화로 하는 것임을 알 수 있다. 따라서 각 쿼리마다 $O(N)$에 해결할 수 있어, 문제를 $O(NQ)$ 에 해결할 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 3 (38점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;각 쿼리에서 트리의 모양은 서브트리의 크기에 따라 유일하게 결정된다. 미리 DP로 이 값들을 구해놓았다면, 적절한 수학적 계산으로 $N$에 대해 현재 서브트리의 크기 값을 구할 수 있다.&lt;br /&gt;&lt;br /&gt;하지만 만점으로 향하는 다른 풀이 방법이 있는데, 바로 트리의 높이 값이 $O(\log N)$으로 매우 작다는 것이다. 정점 $u$가 새로 추가되었다면, $d$값이 수정되는 정점들은 $u$의 조상들 뿐이다. 각 조상 정점에 대해 $d$값을 업데이트하는 것은 자식이 최대 2개이므로 $O(1)$ 가능하다. 따라서 쿼리마다 $O(\log N)$에 모든 값들을 업데이트할 수 있다.&lt;br /&gt;&lt;br /&gt;실제로 구해야 하는 값은 $d$값이 아닌, 각 정점 $u$에 대해 ($u$를 LCA로 하는 모든 경로들에 대해 지나는 부가 진화의 경로의 최댓값)의 최댓값이다. $sub_u$를 $u$의 서브트리만 고려했을 때 최댓값이라 하자. 이 값들도 같은 방법으로 업데이트할 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 4 (59점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;핵심적인 관찰은 최종 트리에서 DP값들이 $O(\log N)$이라는 것이다. 증명은 다양한 방법으로 가능한데, 간단하고 재밌는 증명을 소개한다. 결국 주요 진화와 부가 진화로 나누는 과정이 Heavy-Light Decomposition에서 heavy edge와 light edge로 나누는 과정과 일치하기 때문에, Heavy-Light Decomposition은 가능한 진화 분류 방법 중 하나이고, 이 경우 답이 $O(\log N)$이기 때문에, 최적의 방법 또한 $O(\log N)$이다.&lt;br /&gt;&lt;br /&gt;이제 서브태스크 3의 두 번째 풀이와 비슷하게, 각 조상 정점에 대해 DP값을 업데이트한다. 그냥 모든 조상에 대해 업데이트를 시도하는 것은 은 이제 각 정점의 깊이가 $O(N)$이기 때문에 느리지만, 어떤 정점 $v$에서 $d$값이 바뀌지 않았다면, $v$의 조상들에 대해서도 $d$값이 바뀌지 않는다는 점을 이용해 바로 종료하는 최적화를 해 주자. $sub$에 대해서도 동일하다.&lt;br /&gt;&lt;br /&gt;모든 쿼리에 대해, 총 업데이트의 수가 $O(\sum_u (d_u + sub_u) + Q)$임을 알 수 있다. $d_u$와 $sub_u$가 $O(\log N)$이므로, 문제를 $O(N \log N + Q)$에 해결할 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (100점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제 정점 $u$에 대해 자식들이 매우 많을 수 있기 때문에, 더 효율적으로 $d_u$와 $sub_u$ 값들을 업데이트해야 한다. 이 처리만 해 준다면 서브태스크 4의 풀이를 그대로 적용할 수 있다.&lt;br /&gt;&lt;br /&gt;쉽게 생각할 수 있는 방법으로는 std::multiset 등의 자료구조를 이용해 자식들의 $d_c$값을 관리하는 것이다. $d_u$ 값은 $d_c$의 최댓값 3개에 따라 정해지고, $sub_u$는 자식들의 $sub_u$의 최댓값과 $d_c$의 최댓값 3개에 따라 정해지기 때문에, $O(\log N)$에 새로운 $d_u$값과 $sub_u$값을 구할 수 있다. 시간복잡도는 $O(N \log^2 N + Q \log N)$이다. 조금 커 보이지만 굉장히 빠르게 돌아간다.&lt;br /&gt;&lt;br /&gt;하지만 조금 더 생각해본다면, 이 $d_c$의 최댓값 3개를 어렵지 않게 $O(1)$에 관리할 수 있다. 특히, $d$값이 변할 경우 정확히 1 증가함을 이용하면 매우 편하게 짤 수 있다. 시간복잡도는 $O(N \log N + Q)$이다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;1 - 2. 플래피 버드&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (15점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$y$좌표가 변하지 않는 경로도 가능하지만, $X_{i,j} &amp;lt; W$이므로 그 경우 $x$좌표 $W$에서 $y$좌표가 변하는 같은 점수의 경로가 존재한다. 따라서 $y$좌표가 변하는 경로만 고려하자. $y$좌표가 상승 또는 하강할 수 있는데, 상승하는 경로만 고려하자.&amp;nbsp; 하강하는 경로는 좌표를 뒤집으면 같은 방법으로 해결할 수 있다. 또한, 편의상 $X_{1,i} \le X_{2,i}$, $Y_{1,i} \le Y_{2,i}$를 가정한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;경로를 $0 \le x \le W$, $0 \le y_1 &amp;lt; y_2 \le H$인 $(x,y_1,y_2)$로 표현할 수 있다: $(0,y_1) \to (x,y_1) \to (x,y_2) \to (W,y_2)$. 서브태스크 5에서는 $X_{1,i}=X_{2,i}$이므로 모든 선분이 수직한 선분이다. 이 경우, 선분의 $x$좌표에 따라 $(x,y_1,y_2)$ 경로 상에서 이 선분을 지나는 조건을 다음과 같이 정리할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$X_{1,i} &amp;lt; x$라면 $Y_{1,i} \le y_1 \le Y_{2,i}$이면 선분을 지난다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} = x$라면 $[y_1,y_2]$와 $[Y_{1,i},Y_{2,i}]$가 교점을 가지면 선분을 지난다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} &amp;gt; x$라면 $Y_{1,i} \le y_2 \le Y_{2,i}$이면 선분을 지난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리의 전략은 모든 $x$에 대해, 경로 $(x,y_1,y_2)$의 점수의 최댓값을 구하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$X_{1,i} &amp;lt; x$인 선분들은 $y_1$에, $X_{1,i} &amp;gt; x$인 선분들은 $y_2$에만 의존한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 $X_{1,i} = x$인 선분들을 고려해주자. '$[y_1,y_2]$와 $[Y_{1,i},Y_{2,i}]$가 교점을 가진다'는 $y_1$과 $y_2$에 모두 영향을 받기에 까다로운 조건이다. 대신, $X_{1,i} = x$인 모든 선분들의 가중치 합을 미리 구한 후, 지나지 않는 선분들을 빼 주자. 이 경우, 지나지 않는 선분들은 $Y_{2,i} &amp;lt; y_1$ 또는 $Y_{1,i} &amp;gt; y_2$를 만족하며, 동시에 만족할 수는 없다. 이제 빠지는 각 선분은 $y_1$과 $y_2$ 중 하나에만 의존하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 모든 선분들을 $y_1$과 $y_2$ 중 하나에 의존하게 구분하였다. $L_y$를 $y_1 = y$로 했을 때 더해지는 가중치 합, $R_y$를 $y_2 = y$로 했을 때 더해지는 가중치 합이라 하자. 이제 경로 $(x, y_1, y_2)$의 점수의 최댓값은 $C_{x} + L_{y_1} + R_{y_2}$의 최댓값이다. $C_x$는 $X_{1,i} = x$인 선분들의 가중치 합이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$x = -1$에서, 모든 $L_y = 0$이다. $R_y$는 $Y_{1,i} \le y \le Y_{2,i}$인 선분들의 가중치 합으로, 부분합을 이용하면 $O(H)$에 계산할 수 있다. $x - 1$에서 $x$로 이동할 때, $L$와 $R$배열이 어떻게 바뀌는지 생각해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$X_{1,i} = x - 1$인 선분들에 대해, $L_{Y_{1,i}}, L_{Y_{1,i}+1}, \dots, L_{Y_{2,i}}$에 $A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} = x - 1$인 선분들에 대해, $0 &amp;lt; Y_{1,i}$라면 $L_{0}, L_{1}, \dots, L_{Y_{1,i} - 1}$에 $A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} = x - 1$인 선분들에 대해, $Y_{2,i} &amp;lt; H$라면 $R_{Y_{2,i} + 1}, R_{Y_{2,i}+2}, \dots, R_{H}$에 $A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} = x$인 선분들에 대해, $R_{Y_{1,i}}, R_{Y_{1,i}+1}, \dots, R_{Y_{2,i}}$에 $-A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} = x$인 선분들에 대해, $0 &amp;lt; Y_{1,i}$라면 $L_{0}, L_{1}, \dots, L_{Y_{1,i} - 1}$에 $ - A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} = x$인 선분들에 대해, $Y_{2,i} &amp;lt; H$라면 $R_{Y_{2,i} + 1}, R_{Y_{2,i}+2}, \dots, R_{H}$에 $- A_i$를 더한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lazy Propagation을 사용한 세그먼트 트리로 이 연산들을 구현할 수 있다. $L_{y_1} + R_{y_2}$의 최댓값을 구하기 위해, 각 노드에서 $L_y$의 최댓값, $R_y$의 최댓값, $L_{y_1} + R_{y_2}$의 최댓값을 저장하면 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브태스크 6 (10점)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브태스크 6에서는 $Y_{1,i}=Y_{2,i}$이므로 모든 선분이 수평한 선분이다. 이 경우, 선분의 두 $x$좌표에 따라 $(x,y_1,y_2)$ 경로 상에서 이 선분을 지나는 조건을 다음과 같이 정리할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$X_{2,i} &amp;lt; x$라면 $Y_{1,i}&amp;nbsp; = y_1$이면 선분을 지난다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} \le x \le X_{2,i}$라면 $y_1 \le Y_{1,i} \le y_2$이면 선분을 지난다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} &amp;gt; x$라면 $Y_{1,i} = y_2$이면 선분을 지난다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리의 전략은 서브태스크 5와 동일하게 모든 $x$에 대해, 경로 $(x,y_1,y_2)$의 점수의 최댓값을 구하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$X_{2,i} &amp;lt; x$인 선분들은 $y_1$에, $X_{1,i} &amp;gt; x$인 선분들은 $y_2$에만 의존한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 $X_{1,i} \le x \le X_{2,i}$인 선분들을 고려해주자. $y_1 \le Y_{1,i} \le y_2$는 $y_1$과 $y_2$에 모두 영향을 받기에 까다로운 조건이다. 대신, $X_{1,i} \le x \le X_{2,i}$인 모든 선분들의 가중치 합을 미리 구한 후, 지나지 않는 선분들을 빼 주자. 이 경우, 지나지 않는 선분들은 $Y_{2,i} &amp;lt; y_1$ 또는 $Y_{1,i} &amp;gt; y_2$를 만족하며, 동시에 만족할 수는 없다. 이제 빠지는 각 선분은 $y_1$과 $y_2$ 중 하나에만 의존하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 모든 선분들을 $y_1$과 $y_2$ 중 하나에 의존하게 구분하였다. $L_y$를 $y_1 = y$로 했을 때 더해지는 가중치 합, $R_y$를 $y_2 = y$로 했을 때 더해지는 가중치 합이라 하자. 이제 경로 $(x, y_1, y_2)$의 점수의 최댓값은 $C_{x} + L_{y_1} + R_{y_2}$의 최댓값이다. $C_x$는 $X_{1,i} \le x \le X_{2,i}$인 선분들의 가중치 합이다. 부분합을 이용하면 $O(W)$에 계산할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$x = -1$에서, 모든 $L_y = 0$이다. $R_y$는 $Y_{1,i} = y$인 선분들의 가중치 합이다. $x - 1$에서 $x$로 이동할 때, $L$와 $R$배열이 어떻게 바뀌는지 생각해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$X_{2,i} = x - 1$인 선분들에 대해, $L_{Y_{1,i}}$에 $A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{2,i} = x - 1$인 선분들에 대해, $0 &amp;lt; Y_{1,i}$라면 $L_{0}, L_{1}, \dots, L_{Y_{1,i} - 1}$에 $A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{2,i} = x - 1$인 선분들에 대해, $Y_{1,i} &amp;lt; H$라면 $R_{Y_{1,i} + 1}, R_{Y_{1,i}+2}, \dots, R_{H}$에 $A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} = x$인 선분들에 대해, $R_{Y_{1,i}}$에 $-A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} = x$인 선분들에 대해, $0 &amp;lt; Y_{1,i}$라면 $L_{0}, L_{1}, \dots, L_{Y_{1,i} - 1}$에 $ - A_i$를 더한다.&lt;/li&gt;
&lt;li&gt;$X_{1,i} = x$인 선분들에 대해, $Y_{1,i} &amp;lt; H$라면 $R_{Y_{1,i} + 1}, R_{Y_{1,i}+2}, \dots, R_{H}$에 $- A_i$를 더한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Lazy Propagation을 사용한 세그먼트 트리로 이 연산들을 구현할 수 있다. $L_{y_1} + R_{y_2}$의 최댓값을 구하기 위해, 각 노드에서 $L_y$의 최댓값, $R_y$의 최댓값, $L_{y_1} + R_{y_2}$의 최댓값을 저장하면 된다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브태스크 7 (100점)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브태스크 5와 6을 동시에 하면 된다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;1 - 3. 히스토그램&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 2, 서브태스크 3 (K = 2), 서브태스크 5 (K = 1) (7점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$K = 1$인 문제는 잘 알려진 히스토그램에서 최대 넓이 직사각형을 구하는 문제다. 일반성을 잃지 않고 $H_i$가 모두 다르다고 하자. 히스토그램에서 최대 넓이 직사각형을 구할 때, 우리는 각 $i$에 대해 $H_{L_i},H_{{L_i}+1},\dots,H_{R_i}$중 $H_i$가 최솟값인 가장 긴 구간 $[L_i, R_i]$을 찾는다. 그렇다면 열 $L_i,L_i+1,\dots,R_i$을 차지하는 높이 $H_i$의 직사각형이 답의 후보가 된다. 이 $N$개의 직사각형들을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;최대 직사각형&lt;/b&gt;이라 하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;최대 직사각형들의 가능한 $\binom{N}{K}$개 조합 각각에 대해, $K$개의 직사각형들의 합집합의 영역을 구한다(포함-배제를 이용하면 깔끔하게 구현할 수 있다). 이 영역들만 고려해도 답을 구할 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (K = 2) (28점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$K = 2$에 대해, 최적해의 모양은 다음과 같은 케이스들 중 하나이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;sol-fig1.png&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sKmHw/btrFViztrkP/2hrrjH1delxLUxpGIgjUj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sKmHw/btrFViztrkP/2hrrjH1delxLUxpGIgjUj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sKmHw/btrFViztrkP/2hrrjH1delxLUxpGIgjUj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsKmHw%2FbtrFViztrkP%2F2hrrjH1delxLUxpGIgjUj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;92&quot; data-filename=&quot;sol-fig1.png&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 1에서 최적해가 나온다면, 두 직사각형은 각각 최대 직사각형이다. 그렇지 않다면 좌우로 또는 위로 직사각형을 늘릴 수 있는 방법이 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 2에서 최적해가 나온다면, 직사각형 1은 최대 직사각형이다. 그렇지 않다면 좌우로 직사각형을 늘리거나, 위로 늘려 직사각형 2의 높이를 줄여 더 큰 넓이의 합을 얻을 수 있다. 단, 직사각형 2의 높이가 0이 될 수 있으니 $K = 1$에서의 답도 구해주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 2에서 최적해가 나온다면, 직사격형 2를 아래로 끝까지 늘린 직사각형은 최대 직사각형이다. 그렇지 않다면 좌우로 또는 위로 직사각형을 늘릴 수 있는 방법이 있기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 최대 직사각형들만을 고려해도 $K = 2$에서 답이 나오는 이유를 알았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 1은 스위핑을 통해 어렵지 않게 최댓값을 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대 직사각형들을 분할정복을 통해 구하는 과정은 Cartesian tree를 구하는 과정이다. 각 최대 직사각형을 Cartesian tree의 정점으로 볼 수 있다. 케이스 2는 $u$가 $v$의 조상인 두 정점 $u$와 $v$를 골라야 한다. $H_u D_u + H_v D_v - H_u D_v$가 두 정점을 골랐을 때의 넓이 합이다. $D_u$는 정점 $u$가 나타내는 최대 직사각형의 너비이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 $v$에 대해 최적의 $u$를 구한다. $H_v D_v$는 고정이므로 $ - H_u D_v + H_u D_u$의 최댓값을 구하면 되는데, $F_u(x) = H_u x + H_u D_u$라 정의하면, $-H_u D_v + H_u D_u = F_u(-D_v)$이니, CHT를 사용하면 될 것 같은 모양이 되었다. 트리에서 CHT를&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;$O(N \log N)$에 해결하는 아무 방법을&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;사용하면 된다. 트리에서 CHT는 BOJ 3319번 풀이를 찾아보면 좋은 자료들이 많다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 3 (40점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$K = 3$에 대해, 최적해의 모양은 다음과 같은 케이스들 중 하나이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;sol-fig2.png&quot; data-origin-width=&quot;1389&quot; data-origin-height=&quot;979&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IpFvw/btrFUUyQQOm/1c5oJOgDkBoFTBLP3jq2Uk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IpFvw/btrFUUyQQOm/1c5oJOgDkBoFTBLP3jq2Uk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IpFvw/btrFUUyQQOm/1c5oJOgDkBoFTBLP3jq2Uk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIpFvw%2FbtrFUUyQQOm%2F1c5oJOgDkBoFTBLP3jq2Uk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;211&quot; data-filename=&quot;sol-fig2.png&quot; data-origin-width=&quot;1389&quot; data-origin-height=&quot;979&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 2의 경우는 반대로 직사각형 3이 왼쪽에 있는 경우 또한 포함이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 케이스에 대해, $K = 2$에서와 비슷한 방식으로, 각 직사각형이 아래로 끝까지 늘린 경우 최대 직사각형임을 증명할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 1은 스위핑을 통해 어렵지 않게 최댓값을 구할 수 있다. 이 때, 각 직사각형에 대해 왼쪽과 오른쪽에 있는 직사각형들 중 넓이의 최댓값 $M_i$를 추가로 구해주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 2는 앞에서 구한 $M_i$값을 이용한다.&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;$u$가 $v$의 조상인 두 정점 $u$와 $v$를 골라야 한다. $H_u D_u + H_v D_v - H_u D_v + M_u$가 두 정점을 골랐을 때의 넓이 합이다.&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;$F_u(x) = H_u x + H_u D_u + M_u$로 정의하면, $F_u(-D_v) + H_v D_v$가 되므로 $K = 2$의 케이스 2처럼 트리에서 CHT로 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 3은 $u$가 $v$의 조상이고, $v$가 $w$의 조상인 세 정점 $u,v,w$를 골라야 한다. $H_u (D_u - D_v) + H_v(D_v&amp;nbsp; - D_w) + H_w D_w$가 세 정점을 골랐을 때의 넓이 합이다. $F_u(x)&amp;nbsp; = H_u x + H_u D_u$로 정의하면, $H_u(D_u - D_v)$의 최댓값은 $F_u(-D_v)$의 최댓값이다. $G_v(x) = H_v x + \max F_u(-D_v) + H_v D_v$로 정의하면, 구하는 값은 $w$에 대해 $G_v(w) + H_w D_w$의 최댓값이다. 마찬가지로 트리에서 CHT로 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 4의 경우, $u$가 $v$와 $w$의 조상이고, $v$와 $w$는 서로 조상-자손 관계가 아닌 세 정점 $u, v, w$를 골라야 한다. $H_u (D_u - D_v - D_w) +H_v D_v + H_w D_w$가 세 정점을 골랐을 때의 넓이 합이다. $v$와 $w$가 $u$의 두 자식의 서브트리에서 하나씩 온다고 생각하면 틀리며, 하기 쉬운 실수이니 유의하자. $u$를 고정하고, 각 $u$에 대해 답을 찾는다. $X_i$를 $i$의 서브트리 상의 정점들 $j$에 대해 $H_j D_j - H_u D_j$의 최댓값으로 정의하자. 트리 DP를 이용해 구할 수 있다. $u$의 서브트리 안의 각 정점 $x$에 대해, 해당 정점이 두 개의 자식 $y$와 $z$를 가지면, $H_u D_u + X_y + X_z$가 답의 후보가 된다. 이는 $v$와 $w$의 LCA가 $x$인 경우이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;케이스 4를 제외하면 $O(N \log N)$에, 케이스 4를 $O(N^2)$에 해결했으니 총 시간복잡도는 $O(N^2)$이다. 다른 케이스들도 $O(N^2)$에 더 편하게 구현하는 것도 가능하다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (100점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;케이스 4를 빠르게 해결하는 것이 관건이다. $u$가 $v$와 $w$의 조상이고, $v$와 $w$는 서로 조상-자손 관계가 아닌 세 정점 $u, v, w$를 고르는 것은 굉장히 조건이 많이 달려있어 최적화하기 어렵다. 우리는 이 조건을 완화한다: $v$와 $w$가 서로 조상-자손 관계가 아닌 세 정점 $u,v,w$를 고른다. 즉, $u$가 $v$와 $w$의 조상이라는 조건을 삭제한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 조건을 완화하면, 당연하게도 올바르지 않은 값이 나올 수 있다. 하지만, 이 올바르지 않은 값은 케이스 4의 식대로 했을 때의 올바르지 않은 값이며, 이 경우 $u,v,w$의 위치 관계가 케이스 1, 2에서 고려하는 위치 관계가 된다. 각 경우마다 케이스 1 또는 케이스 2에서 크거나 같은, &quot;올바른&quot; 값을 구했음을 증명할 수 있다. 따라서 이렇게 조건을 완화해도 최종적인 답은 올바르게 구할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제 서로 조상-자손 관계가 아닌 $v$와 $w$에 대해, $F_{v,w}(x)=(D_v + D_w) x + H_v D_v + H_w D_w$로 정의하자. 각 $u$에 대해 $F_{v,w}(-H_u)$의 최댓값을 구해 $H_u D_u$와 더하면 $u$에서의 최댓값을 구할 수 있다. 다시 한 번 CHT를 적용하기 좋은 형태이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$F_{v,w}(x)$들이 총 $O(N^2)$개 있기 때문에, 바로 CHT를 적용하기는 어렵다. 하지만 각 기울기별로 최종 CHT에서는 하나의 직선만이 있을 것이고, 기울기는 $D_v + D_w$이니 $O(N)$개가 존재한다. 즉, 실제로 유의미한 직선들을 빠르게 구할 수 있다면, 문제를 해결할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;유의미한 직선들을 구하는 과정을 분할 정복으로 해결한다. 아이디어는 $v$와 $w$가 서로 조상-자손 관계가 아니라는 것을, $R_v &amp;lt; L_w$로 해석하는 것이다. 즉, $R_v \le x \le L_w$인 $x$가 존재한다. 이를 $x$가 $v$와 $w$의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;분할점&lt;/b&gt;이라는 것으로 정의하자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$F(L,R,A)$을 $A$에 속한 정점들에 대해, $x \in [L, R]$이 분할점으로 가능할 때 유의미한 직선들을 구하는 함수로 정의하자. $L &amp;lt; R$이라면, $M = \left \lfloor \frac{L+R}{2} \right \rfloor$라 하자. $M$이 분할점인 경우를 구한다. $A$에서 $R_v \le M$인 $v$들의 집합을 $X$, $M &amp;lt; L_w$인 $w$들의 집합을 $Y$라 하자. $v \in X, w \in Y$인 모든 $v,w$는 $M$을 분할점으로 가진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$(D_v + D_w) x + H_v D_v + H_w D_w = (D_v x + H_v D_v) + (D_w x + H_w D_w)$이므로, 결국 $X$에서 구할 수 있는 $|X|$개의 직선들과, $Y$에서 구할 수 있는 $|Y|$개의 직선들의 일종의 convolution을 구하는 것이다. 결국, 각 $x$에서 $D_v x + H_v D_v$의 최댓값과 $D_v x + H_w D_w$의 최댓값이 중요하기 때문에 $X$를 이용해 구한 CHT와, $Y$를 이용해 구한 CHT들의 직선들만이 필요한 직선이다. 이 직선들 중에서도 현재 $x$에서 사용되는 직선들만이 중요하므로, 두 CHT들에서의 교점들 사이의 $x$좌표 구간에서는 최적의 직선이 고정된다. 즉, $O(|X|+|Y|)$개의 직선들만이 유의미한 직선들이 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이후, $F(L,M,A_L)$, $F(M+1,R,A_R)$을 호출해 주자. $A_L$은 $v \in A, L_v \le M$인 $v$들이며, $A_R$은 $w \in A, M &amp;lt; R_w$인 $w$들이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;각 $i$는 $O(\log N)$개의 분할정복 함수의 $A$에 들어간다($A$에서 $L_i$와 $R_i$를 서로 구분해서 넣는다고 생각하면 이해하기 쉽다). 따라서 분할 정복의 시간복잡도는 구현에 따라 $O(N \log N)$ 또는 $O(N \log^2 N)$이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;유의미한 직선들의 수를 $O(N \log N)$개로 줄일 수 있었다. 이 직선들을 이용해 CHT를 만들면 $O(N \log ^2N)$이지만, 기울기가 $O(N)$임을 이용해 간단하게 $O(N \log N)$으로 줄일 수 있다. 이제 각 $u$에 대해 최댓값을 구하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이제 케이스 4 또한 $O(N \log N)$에 해결하였으므로, 전체 문제를 $O(N \log N)$에 해결할 수 있다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;1 - 4. 날다람쥐&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (33점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;우선, $(D_N,R)$에 가는 것은 예외처리가 생각보다 까다로우므로, $N+1$번째 기둥을 만들어 $D_{N+1} = D_N + R$, $H_{N+1} = W_{N+1} = 0$이라 합시다. $L$에 대해서도 비슷한 방식으로, $D_{-1} = W_{-1} = 0$, $H_{-1} = L$인 기둥을 만들어 처리가 가능하다. 이제 높이 0에서 출발해 높이 0으로 도달하는 문제가 되었다.&lt;br /&gt;&lt;br /&gt;$i$번째 기둥의 가장 위인 $(D_i,H_i)$에서 오른쪽으로 날아갔을 때, 다음 기둥에 도달하지 못할 수 있다. 이 경우 해당 높이까지 가는 것이 의미가 없으니 $H_i = \min (H_i H_{i+1} + (D_{i+1} - D_i)$로 바꿔줍시다. $i=N$부터 $i=1$까지 순서대로 바꿔주면 된다. 도중에 $H_i &amp;lt; 0$이 된다면 이동이 불가능한 경우로 -1을 반환하면 된다. 추가적인 높이가 왼쪽 위에서 도달할 수 있게 해 주니 유의미하다고 생각할 수 있지만, 높이 감소에는 아무 비용이 들지 않으니 미리 높이를 감소시키고 가면 같은 비용의 경로를 얻을 수 있다.&lt;br /&gt;&lt;br /&gt;이제 $0$부터 $N+1$까지 순서대로, 각 $i$에 대해 $i$번째 기둥까지 도달하는 최소 비용을 구한다. $i-1$번째 기둥까지 도달한 경로를 수정해, 경로가 $i$번째 기둥까지 도달하려면 앞의 기둥들에서 위로 움직여야 한다. 이 때 움직일 기둥은 위로 움직일 수 있는 기둥들 중 $W_j$가 최소인 $j$이다. 움직일 수 있다는 것은 $j$에서 경로를 위로 올리는 것이 나중에 어떤 기둥 $k$에서 $H_k$ 제한에 따라 막히지 않는다는 것을 의미한다.&lt;br /&gt;&lt;br /&gt;따라서 위로 움직일 수 있는 기둥들 중 $W_j$가 최소인 $j$를 도달 가능할 때까지 계속 $O(N)$에 구하면, 각 상황마다 $i$에 도달이 가능해지거나 $j$가 더 이상 움직일 수 없어지기 때문에 $O(N^2)$에 문제를 해결할 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 6 (100점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;위로 움직일 수 있는 기둥들을 데크로 관리한다. 데크 안에서는 DP를 데크를 최적화할 때와 유사하게 비용 오름차순으로 관리한다. 만약 움직일 수 있는 기둥들 $j$와 $k$에 대해 $j &amp;lt; k$이고 $W_j \ge W_k$라면 $k$를 먼저 올라가게 되고, $k$를 모두 올라갔다면 $j$에서도 움직일 수 없게 되기 때문에 $j$는 의미가 없어지기 때문에 이러한 관리가 가능하다.&lt;br /&gt;&lt;br /&gt;이제 $i$번째 기둥에 도달할 때까지 데크의 가장 앞 기둥에서 가능한 최대 높이까지 올라가는 것을 반복하고, 이후 $i$번째 기둥을 이용해 데크의 뒤에서 $W_j \ge W_i$인 기둥들을 빼 주고, 마지막으로 데크의 뒤에 기둥 $i$를 넣으면 된다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;2 - 1. 코딩 테스트&lt;/h2&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;앞으로 1-based를 가정한다. 문제에서는 쿼리가 $L$과 $U$로 주어지지만, 앞으로 $l$과 $r$으로 설명합니다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 2 (18점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;답에 대한 이분 탐색을 하자. 답이 $X$ 이상인지 판단하는 결정 문제를 해결하자. $l$부터 $r$까지 순서대로, 우선 $A_i$개의 문제는 반드시 고를 수 있고, 이후 $B_{i-1}$개의 문제들 중 $i-1$번 문제가 사용하고 남은 문제들도 반드시 사용하는 것이 이득이다. 아직도 남은 문제가 있다면 $B_i$에서 남은 수만큼 추가로 문제를 사용해야 한다. 전부 사용해도 $X$ 미만이면 불가능한 경우이다. $r$까지 모든 난이도의 문제를 배정했다면 가능한 경우다. 각 결정문제를 해결하는 데에 $O(N)$ 시간이 필요하므로, 총 $O(NM\log 3 \times 10^8)$에 해결할 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 3 (54점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;쿼리 $[l, r]$에 대해, 쿼리의 답은 $\min_{l \le i \le j \le r} \left \lfloor \frac{A_i + \cdots + A_j + B_{i-1} + B_i + \cdots + B_j}{j - i +1} \right \rfloor$이다. 증명은 앞의 이분 탐색 풀이를 이용하거나, 홀의 정리를 이용하면 된다. 이분 탐색 풀이를 이용한 증명의 경우, 결국 결정 문제에서 불가능을 판단하는 데에 사용하는 값들이 저 꼴임을 관찰하자. 홀의 정리를 이용한 증명의 경우, 저 값은 연속한 난이도 집합을 기준으로 한 상한이고, 항상 최소 상한은 연속한 난이도 집합을 뽑을 때 나옴을 관찰하자.&lt;br /&gt;&lt;br /&gt;$S_i = A_1 + \cdots + A_i + B_1 + \cdots + B_{i-1}$, $T_i = A_1 + \cdots + A_i + B_1 + \cdots + B_i$로 정의하자. 그러면 쿼리의 답이 $\min_{l - 1 \le i &amp;lt; j \le r} \left \lfloor \frac{T_j - S_i}{j - i + 1} \right \rfloor$이 된다.&lt;br /&gt;&lt;br /&gt;$D_{l,r}$를 $[l, r]$쿼리에 대한 답이라 한다면, $D_{l,r}=\min(D_{l,r-1},D_{l+1,r},\left \lfloor \frac{T_r - S_{l-1}}{r-l+1} \right \rfloor)$이다. $O(N^2)$에 값들을 계산한 후 각 쿼리는 $O(1)$에 해결할 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 4 (77점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;모든 접두사에 대해 답을 구하면 된다. $j$번째 접두사에서의 답은 $j-1$번째 접두사에서의 답과, $\min_{0 \le i &amp;lt; j}^{} \left \lfloor \frac{T_j - S_i}{j - i} \right \rfloor$ 중 최솟값이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;$\min_{0 \le i &amp;lt; j}^{} \frac{T_j - S_i}{j - i}$ 를 구하는 방법은 여러가지가 있는데, 이 값을 $(i, S_i)$와 $(j, T_j)$를 잇는 기울기라 생각한다면, Andrew's monotone chain 알고리즘을 이용해 $(i, S_i)$들의 윗쪽 볼록 껍질을 관리하면, $(j, T_j)$에 대해 이 볼록 껍질로 이은 접선의 기울기가 된다. 이 방법을 이용하면 $O(N \log N)$에 모든 답을 구할 수 있다.&lt;br /&gt;&lt;br /&gt;또는 이 값에 대한 이분 탐색을 시도할 수 있다. $\min_{0 \le i &amp;lt; j} \frac{T_j - S_i}{j - i}$가 $X$ 이상이라는 것은 $\min_{0 \le i &amp;lt; j} (-jX + T_j) + (iX - S_i) \ge 0$이라는 뜻이고, 이는 CHT를 이용해 $O(\log N)$에 판단할 수 있어, 모든 답을 $O(N \log N \log 3 \times 10^8)$에 구할 수 있다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (100점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;분할 정복을 이용해 문제를 해결한다. $[s, e]$에 대해, $r &amp;lt; m = \frac{s+e}{2}$인 쿼리들은 $[s, m]$에서, $m &amp;lt; l - 1$인 쿼리들은 $[m+1, e]$에서 해결하도록 넘겨준다. $s \le l -1 \le m &amp;lt; r \le e$인 쿼리들을 이제 한 번에 해결한다.&lt;br /&gt;&lt;br /&gt;$j \le m$인 경우, $m &amp;lt; i$인 경우, $i \le m &amp;lt; j$인 경우를 모두 고려하면 $\min_{l - 1 \le i &amp;lt; j \le r} \left \lfloor \frac{T_j - S_i}{j - i + 1} \right \rfloor$을 구할 수 있다.&lt;br /&gt;&lt;br /&gt;$j \le m$인 경우와 $m &amp;lt; i$인 경우는 각각 $[s, m]$에서의 접미사와 $[m+1, e]$에서의 접두사에서의 문제이므로 서브태스크 4의 풀이를 이용해 해결할 수 있다. 풀이에 따라 $O(N \log^2 N)$이나 $O(N \log^2N \log 3 \times 10^8)$이 걸린다.&lt;br /&gt;&lt;br /&gt;$i \le m &amp;lt; j$인 경우는 서브태스크 4의 이분 탐색 풀이를 응용해 해결한다. $\min_{l - 1 \le i \le m &amp;lt; j \le r} \frac{T_j - S_i}{j - i + 1}$가 $X$ 이상인지 판단하는 결정 문제를 해결하자. $[l, m]$에서 $iX - S_i$의 최솟값과 $[m+1,r]$에서 $-jX + T_j$의 최솟값을 각각 CHT로 구한 다음, 합한 값이 0 이상인지 확인하면 된다. 접두사/접미사 CHT 쿼리가 필요한데, persistent CHT를 이용하는 방법 등이 가능하겠지만 parallel binary search를 사용하면 복잡한 자료구조 없이도 가능하다. 시간복잡도는 $O(N \log N \log 3 \times 10^8 + Q \log N \log 3 \times 10^8)$이다.&lt;br /&gt;&lt;br /&gt;서브태스크 4의 볼록 껍질 풀이를 응용한 방식으로도 문제를 해결할 수 있다. 결정 문제를 해결하는 등 다양한 방법이 가능하다. 시간복잡도는 $O(N \log^2 N + Q \log N \log 3 \times 10^8)$, $O((N + Q) \log^2 N)$ 등 다양한 듯 하다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;2 - 2. 알록달록한 괄호열&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 4 (76점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$D_{0,l,r}$을 괄호열의 $[l,r]$ 구간만 고려했을 때, $l$과 $r$의 괄호는 반드시 사용하며, $l$의 괄호와 $r$과 괄호가 짝지어질 때 뽑아낼 수 있는 알록달록한 괄호열의 수, $D_{1,l,r}$을 괄호열의 $[l,r]$ 구간만 고려했을 때, $l$과 $r$의 괄호는 반드시 사용할 때 뽑아낼 수 있는 알록달록한 괄호열의 수라고 정의하자.&lt;br /&gt;&lt;br /&gt;$l$이 닫는 괄호이거나 $r$이 여는 괄호라면 $D_{0,l,r}=D_{1,l,r}=0$이다. $l$과 $r$이 색이 같다면 $D_{0,l,r}=0$이다.&lt;br /&gt;&lt;br /&gt;우선, $D_{0,l,r}$을 계산하자.&lt;br /&gt;&lt;br /&gt;우선, $l$과 $r$만 있는 경우가 하나 있다.&lt;br /&gt;&lt;br /&gt;이제 안에 추가로 괄호가 있는 경우를 생각해보자. $l$ 왼쪽의 괄호가 $i$, $r$ 오른쪽의 괄호가 $j$인 경우를 생각해보자. $i$는 $A_i &amp;lt; 0, A_i \neq A_l$을 만족해야 하고, $j$는 $A_j &amp;gt; 0, A_j \neq A_r$를 만족해야 한다. 또한, 중복해서 세지 않기 위해서 $i$는 색이 $-A_i$인 위치들 중 가장 앞에 오는 $i$이고, $j$는 색이 $A_j$인 위치들 중 가장 뒤에 오는 $j$여야 한다. 이를 만족하는 모든 $(i,j)$에 대해 $D_{1,i,j}$를 더해주면 된다.&lt;br /&gt;&lt;br /&gt;다음으로, $D_{1,l,r}$을 계산하자.&lt;br /&gt;&lt;br /&gt;우선, $l$과 $r$이 서로 짝지어진 경우인 $D_{0,l,r}$이 있다.&lt;br /&gt;&lt;br /&gt;이제 $l$과 $r$이 서로 짝지어지지 않은 경우를 생각해보자. $l$과 짝지어진 괄호가 $i$, $i$ 이후 첫 괄호가 $j$인 경우를 생각해보자. $i$는 $A_i &amp;gt; 0, A_i \neq -A_l$을 만족해야 하고, $j$는 $A_j &amp;lt; 0, A_j \neq - A_i$을 만족해야 한다. 또한, 중복해서 세지 않기 위해서 $j$는 색이 $-A_j$인 위치들 중 $i$ 이후 가장 앞에 오는 $j$여야 한다.&lt;br /&gt;&lt;br /&gt;단순하게 생각한다면 경우의 수는 $D_{0,l,i}D_{1,j,r}$이다. 하지만 우리는 $j$에 대한 중복 계산을 고려했지만, $i$에 대한 중복 계산은 고려하지 않았다. $i$ 이전에 이미 색이 $A_i$인 위치들이 있었다면, 해당 위치들에서 이미 계산한 값들을 빼 줘야 한다. $i$ 바로 전에 등장한 $A_i$의 위치가 $bef(i)$라면, $l &amp;lt; bef(i)$라면 $D_{0,l,bef(i)}D_{1,j,r}$을 빼 주면 된다.&lt;br /&gt;&lt;br /&gt;답은 $A_i &amp;lt; 0$이고 색이 $-A_i$인 위치들 중 가장 앞에 오는 $i$와, $A_j &amp;gt; 0$이고 색이 $A_j$인 위치들 중 가장 뒤에 오는 $j$들에 대해 $D_{1,i,j}$의 합이다. 하나의 DP값을 계산하는 데에 각 경우 $O(N^2)$가 걸려, 모든 DP값들을 채우는 데에 걸리는 시간은 $O(N^4)$이다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (100점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$D_{1,l,r}$은 $i$를 $l+1$부터 $r-1$까지 증가시키면서 먼저 각 $i$에 대해 $D_{0,l,i}$와 $D_{0,l,bef(i)}$를 구한 후, $i$를 $r-1$부터 $l+1$까지 감소시키면서 현재 각 색에 대해 가장 최근에 등장한 $j$들에 대해 $D_{1,j,r}$ 값들과 그 합을 관리하면 어렵지 않게 $O(N)$에 구할 수 있다.&lt;br /&gt;&lt;br /&gt;$D_{0,l,r}$은 결국 $nxt(i)$를 $i$ 바로 다음에 등장한 $A_i$의 위치라 한다면, $bef(i) &amp;lt; l, l &amp;lt; i &amp;lt; r$인 $i$와 $nxt(j) &amp;gt; r, l &amp;lt; j &amp;lt; r$인 $j$에 대해 $D_{1,i,j}$의 합에 1을 더한 것이다. 반대로 각 $(i,j)$에 대해, 해당하는 $(l,r)$에 $D_{1,i,j}$를 더해준다고 생각하면, 직사각형 $[bef(i)+1, i-1] \times [j+1, nxt(j)-1]$에 $D_{1,i,j}$를 더하게 된다. 부분합으로 생각한다면 $(i-1,j+1)$과 $(bef(i), nxt(j))$에 $D_{1,i,j}$를 더하고, $(bef(i), j+1)$, $(i-1, nxt(j))$에 $D_{1,i,j}$를 더했을 때, $D_{0,l,r}$은 $x$가 $l$ 이상이고, $y$가 $r$ 이하인 $(x,y)$들의 값의 합에 1을 더한 것이다. 이렇게 생각하면 $r-l$이 증가하는 순서로 순회할 때 함께 계산이 가능함을 알 수 있다.&lt;br /&gt;&lt;br /&gt;따라서 $O(N^3)$에 문제를 해결할 수 있다.&lt;/p&gt;
&lt;h2 style=&quot;text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;2 - 3. 마법 구슬 찾기&lt;/h2&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (29점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;$D_k$를 일반 구슬 $k-1$개와 마법 구슬 $1$개가 있을 때, 마법 구슬을 찾는 데에 필요한 비용이라 정의하자. $D_0 = -\infty,D_1=0$이다.&lt;br /&gt;&lt;br /&gt;$D_k$를 이분 탐색을 이용해 구한다. $X$원이 있을 때 마법 구슬을 찾을 수 있는 지 판단하는 결정 문제를 해결하자. 각 주머니 $i$에 대해, 이 주머니에 $Y$개의 구슬을 넣었다면, 해당 주머니에 마법 구슬이 있을 때 비용은 $A_i Y + B_i$원이고, $Y$개의 구슬에 대해 문제를 다시 해결해야 하므로 $D_Y$원만큼 추가로 비용이 든다. 즉, $i$번 주머니에는 $A_i Y + B_i + D_Y \le X$인 최대 $Y$만큼의 구슬을 넣을 수 있다. $Y$는 다시 이분 탐색을 이용해 찾으면 된다.&lt;br /&gt;&lt;br /&gt;모든 주머니에 대해 넣을 수 있는 구슬의 개수의 합이 $k$ 이상이라면 $X$원으로 마법 구슬을 찾을 수 있다. 시간복잡도는 $O(NM \log Ans \log N)$이다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 6 (53점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;서브태스크 5의 이분 탐색의 결정 문제는 마지막에 구슬의 개수의 합이 $k$ 이상인지를 비교하는 것만 제외하면 $k-1$에서의 결정 문제와 동일하다. 또한 자명히 $k-1$개의 구슬에서의 답은 $k$개의 구슬에서의 답 이하이다. 또, $X$원이 있을 때 각 주머니에 넣을 수 있는 구슬의 수는 $X &amp;lt; X'$인 $X'$원이 있을 때 각 주머니에 넣을 수 있는 구슬의 수 이하이다.&lt;br /&gt;&lt;br /&gt;위의 관찰들을 바탕으로 느리지만 올바른 다음과 같은 풀이를 얻을 수 있다: 현재 $k-1$에서의 답 $D_{k-1}$에 대해, $X=D_{k-1}$원이 있을 때 각 주머니에 넣은 구슬의 개수를 가지고 있다. $X$를 계속 1씩 증가시킨다. 만약 어떤 주머니에 구슬을 추가로 넣을 수 있는 시점이 되었다면, 그 주머니에 구슬을 추가로 넣는다. $D_k$는 현재 시점의 $X$이다.&lt;br /&gt;&lt;br /&gt;$X$를 1씩 증가시키면 느리지만, 각 주머니 $i$에 대해 구슬을 하나 더 넣기 위해 필요한 최소 $X$는 현재 구슬의 개수 $C_i$에 대해, $A_i (C_i + 1) + B_i + D_{C_i + 1}$이다. 모든 $i$에 대해 해당 값들 중 최솟값이 $D_k$가 되고, 해당 주머니에 구슬을 하나 더 넣어 $C_i$를 1 증가시키면 된다. 시간복잡도는 $O(NM)$이다.&lt;br /&gt;&lt;br /&gt;유의할 점은 $C_i + 1 = N$이 되면 식이 이상해진다는 것이다. 하지만 2 이상의 $N$에 대해선 반드시 처음에 서로 다른 주머니들에 구슬을 넣어야 한다. 즉 $D_2$까지만 따로 처리해주면 아무 문제가 생기지 않는다. 구슬이 2개일 때에는 $A_i + B_i$가 가장 작은 두 주머니에 구슬을 넣으면 되고, 필요한 최소 비용은 $A_i+B_i$의 두 번째 최솟값이다. $A_i + B_i$가 가장 작은 두 개의 주머니에는 구슬을 하나씩 넣어 $C_i=1$이고, 나머지 주머니는 $C_i=0$이다.&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;서브태스크 7 (100점)&lt;/h3&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;서브태스크 6의 풀이를 우선순위 큐를 이용해 최적화한다. 시간복잡도는 $O((M + N) \log M)$이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2 - 4. 보안 시스템&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브태스크 1 (5점)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 가능한 $2^N$개의 방법에 대해, 실제로 가능한 경우인지 확인해 본다. $O(N^2)$에 체크해 $O(2^N N^2)$에 구현해도 충분하다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브태스크 2 (13점)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;meet in the middle 기법을 사용한다. 크기 $\frac{N}{2}$의 두 집합으로 나눈 후, 각 집합에 대해 가능한 모든 조합들을 구한다. 왼쪽 집합의 조합 $S$에 대해, 오른쪽 집합에서 $S$와 겹치지 않는 센서들의 집합을 $F(S)$라 하자. 오른쪽 집합의 조합 $T$를 $S$와 함께 사용할 수 있는 조건은 $T \subseteq F(S)$이다. SOS DP를 이용하면 $F(S)$에 대해 가장 가중치 합이 큰 $T$를 구할 수 있다. $O(2^{\frac{N}{2}} N^2)$ 등에 구현하면 된다. 최적화가 잘 된 백트래킹도 통과한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브태스크 5 (24점)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 $x$좌표가 작은 오른쪽 방향 센서를 $P(x_P,y_P)$로 고정하자. 이제 좌표평면의 각 영역을 다음과 같이 구분할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$x &amp;lt; x_P$인 영역에서는 위쪽 방향 센서와 아래쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \ge x_P, y \ge y_P$인 영역에서는 위쪽 방향 센서와 오른쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \ge x_P, y &amp;lt; y_P$인 영역에서는 아래쪽 방향 센서와 오른쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 그림은 $P$에 대해서 나누어진 영역들을 나타낸다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;294&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E4XcJ/btrVpYMGirU/T3b6xZiOKnTNYfyVdHkKK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E4XcJ/btrVpYMGirU/T3b6xZiOKnTNYfyVdHkKK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E4XcJ/btrVpYMGirU/T3b6xZiOKnTNYfyVdHkKK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE4XcJ%2FbtrVpYMGirU%2FT3b6xZiOKnTNYfyVdHkKK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;294&quot; height=&quot;294&quot; data-origin-width=&quot;294&quot; data-origin-height=&quot;294&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 영역은 다이나믹 프로그래밍을 이용해 $O(N^2)$ 전처리 후 $O(1)$에 가중치 합의 최댓값을 구할 수 있다. 모든 오른쪽 방향 센서에 대해서 해당 센서가 가장 $x$좌표가 작은 오른쪽 방향 센서인 경우의 최댓값을 구하면 된다. 오른쪽 방향 센서를 사용하지 않는 경우도 처리해야 함에 유의하자.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브태스크 3 (45점)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브태스크 5의 풀이를 확장한다. 가장 $x$좌표가 큰 왼쪽 방향 센서를 $P(x_P,y_P)$로 고정하고, 가장 $x$좌표가 작은 오른쪽 방향 센서를 $Q(x_Q,y_Q)$로 고정하자. 이 때, $x_P &amp;lt; x_Q$를 가정하자. 이제 좌표평면의 각 영역을 다음과 같이 구분할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$x \le x_P, y \ge y_P$인 영역에서는 위쪽 방향 센서와 왼쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \le x_P, y &amp;lt; y_P$인 영역에서는 아래쪽 방향 센서와 왼쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x_P &amp;lt; x &amp;lt; x_Q$인 영역에서는 위쪽 방향 센서와 아래쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \ge x_Q, y \ge y_Q$인 영역에서는 위쪽 방향 센서와 오른쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \ge x_Q, y &amp;lt; y_Q$인 영역에서는 아래쪽 방향 센서와 오른쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 그림은 $P$와 $Q$에 대해서 나누어진 영역들을 나타낸다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;294&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clDqrz/btrVjSgjKNP/DTwGylR2i8YkPz4YBuDoN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clDqrz/btrVjSgjKNP/DTwGylR2i8YkPz4YBuDoN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clDqrz/btrVjSgjKNP/DTwGylR2i8YkPz4YBuDoN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclDqrz%2FbtrVjSgjKNP%2FDTwGylR2i8YkPz4YBuDoN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;291&quot; height=&quot;294&quot; data-origin-width=&quot;291&quot; data-origin-height=&quot;294&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브태스크 5와 같은 다이나믹 프로그래밍으로 $O(1)$에 최댓값을 구할 수 있다. 가능한 쌍이 총 $O(N^2)$이니, $x_P &amp;lt; x_Q$인 경우는 $O(N^2)$에 최댓값을 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 가장 $y$좌표가 큰 아래쪽 방향 센서를 $R(x_R,y_R)$로 고정하고, 가장 $y$좌표가 작은 위쪽 방향 센서를 $S(x_S,y_S)$로 고정하자. 이 때, $y_R &amp;lt; y_S$를 가정하자. 위의 풀이에서 좌표를 90도 회전한 이후 동일한 방식으로 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 남은 경우는 $x_P \ge x_Q$, $y_R \ge y_S$인 경우이다. 일반성을 잃지 않고 $y_P &amp;lt; y_Q$를 가정하자. 네 개의 센서가 서로 겹치지 않아야 하므로, $x_S &amp;lt; x_Q \le x_P &amp;lt; x_R$, $y_P &amp;lt; y_S \le y_R &amp;lt; y_Q$를 만족한다. 즉, 아래 그림과 같이 소용돌이 모양을 만든다. $y_P &amp;gt; y_Q$인 경우는 90도 회전한 이후 다시 해결하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;297&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmdfye/btrVkcsi9To/skGA7m60FrIn63soAGpQ3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmdfye/btrVkcsi9To/skGA7m60FrIn63soAGpQ3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmdfye/btrVkcsi9To/skGA7m60FrIn63soAGpQ3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbmdfye%2FbtrVkcsi9To%2FskGA7m60FrIn63soAGpQ3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;297&quot; height=&quot;300&quot; data-origin-width=&quot;297&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 좌표평면의 각 영역을 다음과 같이 구분할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$x \le x_P, y \le y_P$인 영역에서는 아래쪽 방향 센서와 왼쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \le x_P, y_P &amp;lt; y &amp;lt; y_S$인 영역에서는 왼쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \ge x_Q, y \ge y_Q$인 영역에서는 위쪽 방향 센서와 오른쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \ge x_Q, y_R &amp;lt; y &amp;lt; y_Q$인 영역에서는 오른쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \ge x_R, y \le y_R$인 영역에서는 아래쪽 방향 센서와 오른쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x_P &amp;lt; x &amp;lt; x_R, y \le y_R$인 영역에서는 아래쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x \le x_S, y \ge y_S$인 영역에서는 위쪽 방향 센서와 왼쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x_S &amp;lt; x &amp;lt; x_Q, y \ge y_S$인 영역에서는 위쪽 방향 센서만이 존재한다.&lt;/li&gt;
&lt;li&gt;$x_Q \le x \le x_P, y_S \le y \le y_R$인 영역에서는 센서가 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 그림은 $P$와 $Q$, $R$과 $S$에 대해서 나누어진 영역들을 나타낸다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;231&quot; data-origin-height=&quot;233&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cTutui/btrVnZThXuu/L0naeKuEpyWVZrWWFVUEK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cTutui/btrVnZThXuu/L0naeKuEpyWVZrWWFVUEK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cTutui/btrVnZThXuu/L0naeKuEpyWVZrWWFVUEK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcTutui%2FbtrVnZThXuu%2FL0naeKuEpyWVZrWWFVUEK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;231&quot; height=&quot;233&quot; data-origin-width=&quot;231&quot; data-origin-height=&quot;233&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에도 다이나믹 프로그래밍을 이용한 $O(N^2)$ 전처리 후 $O(1)$에 가중치 합의 최댓값을 얻을 수 있다. 가능한 쌍이 총 $O(N^4)$이니, 이 경우는 $O(N^4)$에 최댓값을 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 영역 분리를 조금 단순화해서 해결하는 방법도 가능하다. $x \le x_P, y_P &amp;lt; y &amp;lt; y_S$인 영역에서도 아래쪽 방향 센서를 허용한다고 한 후, $x \le x_P, y &amp;lt; y_S$인 영역에 대해, 아래쪽 방향 센서와 왼쪽 방향 센서만 존재할 경우의 최댓값을 구하자. 이렇게 구한 값은 $P$가 가장 $x$좌표가 큰 왼쪽 방향 센서라는 제약을 어길 수 있지만, 올바른 배치를 만들기에 그대로 사용해도 무방하다. 이런 방식을 통해 영역들을 4개의 꼭짓점을 포함한 영역들과 센서가 존재하지 않는 중앙의 영역으로 단순화할 수 있다. 이 경우 중요한 좌표의 수가 4개이므로 $O(N^4)$에 해결할 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브태스크 4 (60점)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$R$과 $S$를 고정하자. 센서가 존재할 수 있는 영역만 고려한다면, $P$에 의해 나뉘는 센서가 영역들과 $Q$에 의해 나뉘는 영역들이 서로 구분된다. $x$좌표를 증가시키면서 현재 가능한 $Q$들 중 $Q$에 의해 나뉘는 영역들의 가중치 합이 최대인 것을 관리하자. 이제 가능한 $P$를 만날 때마다 최댓값을 구할 수 있어, 고정된 $R$과 $S$에 대해 $O(N)$에 문제를 해결할 수 있다. 따라서 문제를 $O(N^3)$에 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서브태스크 3의 단순화된 영역 분리를 이용한 풀이도 비슷한 방법으로 $O(N^3)$으로 최적화할 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브태스크 6 (77점)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$R$을 고정한 후, 각 $S$에 대해 최적의 $(P, Q)$ 쌍을 찾을 것이다. 이를 위해, 각 영역의 값을 어떻게 배정할 것인지를 결정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, $R$이 고정되었으므로 $x \ge x_R, y \le y_R$인 영역은 고정된다. 따라서 이 영역의 값은 상수로 취급한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$P$를 고정했을 경우, 추가적으로 고정되는 영역들은 다음과 같다. 이 두 영역들의 값은 $P$에 배정된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$x \le x_P, y \le y_P$인 영역&lt;/li&gt;
&lt;li&gt;$x_P &amp;lt; x &amp;lt; x_R, y \le y_R$인 영역&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$Q$를 고정했을 경우, 추가적으로 고정되는 영역들은 다음과 같다. 이 두 영역들의 값은 $Q$에 배정된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$x \ge x_Q, y \ge y_Q$인 영역&lt;/li&gt;
&lt;li&gt;$x \ge x_Q, y_R &amp;lt; y &amp;lt; y_Q$인 영역&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$P$와 $Q$의 조합을 고정했을 경우 $S$에 따라 결정되는 영역들은 다음과 같다. 가운데의 센서가 없는 영역은 제외했다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;$x \le x_P, y_P &amp;lt; y &amp;lt; y_S$인 영역&lt;/li&gt;
&lt;li&gt;$x \le x_S, y \ge y_S$인 영역&lt;/li&gt;
&lt;li&gt;$x_S &amp;lt; x &amp;lt; x_Q, y \ge y_S$인 영역&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$x \le x_S, y \ge y_S$인 영역은 $S$가 고정되었을 경우 고정되므로, $S$에 배정된다. 나머지 두 영역은 특정 점에 배정할 수 없으며 $P, Q, S$의 선택에 따라 바뀐다. 즉, $P, Q, S$에 대한 값은 $C_P + C_Q + C_S + f(P, S) + g(Q, S)$의 꼴로 표현할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리의 전략은 $y = 0$에서 시작해, $y$좌표를 올리면서 가능한 $P$와 $Q$들에 대해 현재 비용, 즉 $C_P + f(P, S)$와 $C_Q + g(Q, S)$를 관리하고 가능한 $S$를 만나면 최적의 $(P, Q)$ 쌍을 찾는 것이다. 가능한 $Q$들은 $R$에 따라 고정이지만, 가능한 $P$들은 $y$좌표를 올리면서 점점 늘어남에 유의하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$f(P, S)$는 $x \le x_P, y_P &amp;lt; y &amp;lt; y_S$인 영역에서 왼쪽 방향 센서들의 가중치 합이다. 이는 $y$좌표를 올리며 왼쪽 방향 센서 $A(x_A, y_A)$를 만난 경우, $x_A \le x_P$를 만족하는 $P$들에 대해 $w_A$를 더해주는 방식으로 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$g(Q, S)$는 $x_S &amp;lt; x &amp;lt; x_Q, y \ge y_S$인 영역에서 위쪽 방향 센서들의 가중치 합이다. 이를 ($x &amp;lt; x_Q, y \ge y_S$인 영역에서 위쪽 방향 센서들의 가중치 합) $-$ ($x \le x_S, y \ge y_S$인 영역에서 위쪽 방향 센서들의 가중치 합)으로 처리하자. 이제 $x \le x_S, y \ge y_S$인 영역은 $S$에 배정할 수 있다. $x &amp;lt; x_Q, y \ge y_S$인 영역에서 위쪽 방향 센서들의 가중치 합은 $y$좌표를 올리며 위쪽 방향 센서를 $A(x_A, y_A)$를 만난 경우, $x_A &amp;lt; x_Q$를 만족하는 $Q$들에 대해 $w_A$를 빼 주는 방식으로 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, $f(P, S)$와 $g(Q, S)$를 $x$좌표 구간에 대한 덧셈 연산을 통해 관리할 수 있다. $f(P, S)$ 또는 $g(Q, S)$에 대한 구간 덧셈 연산, $x_S &amp;lt; x_Q \le x_P$를 만족하는 $(P, Q)$에 대해 $C_P + C_Q + f(P, S) + g(Q, S)$의 최댓값을 구하는 연산이 필요하다. 이는 세그먼트 트리를 이용해 각 연산 당 $O(\log N)$에 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 $R$이 고정된 경우의 최댓값을 $O(N \log N)$에 구할 수 있어, 전체 문제를 $O(N^2 \log N)$에 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 서브태스크의 경우 의도되지 않은 다른 풀이가 있다. 왼쪽/오른쪽 방향 센서끼리는 서로 겹치지 않고, 위쪽/아래쪽 방향 센서끼리는 서로 겹치지 않는다. 즉, 교차 관계를 그래프로 표현할 경우 이 그래프는 이분 그래프이다. 이분 그래프에서 최대 가중치 독립 집합을 구해야 한다. 이는 Min Cut Max Flow 정리를 이용해 해결할 수 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서브태스크 7 (100점)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떠한 센서가 바라보는 방향에 같은 방향의 더 큰 가중치를 가진 센서가 있다면 이 센서는 의미가 없고, 지워도 무방하다. 이 처리를 통해 무의미한 센서들을 미리 지워주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 좌표를 가진 센서들이 여럿 있을 수 있으므로 $f(P, S)$와 $g(Q, S)$를 이제는 다순히 가중치 합으로 처리할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$f(P, S)$는 $y_P &amp;lt; y &amp;lt; y_S$를 만족하는 각 $y$에 대해, $x \le x_P$를 만족하는 왼쪽 방향 센서들의 가중치 중 최댓값의 합이다. 앞에서 무의미한 센서들을 지웠기 때문에 $x \le x_P$를 만족하는 센서들 중 가장 $x$좌표가 큰 센서가 우리가 원하는 센서이다. $y$좌표를 올리며 왼쪽 방향 센서 $A(x_A, y_A)$를 만난 경우, $A$가 최적인 $x$좌표 구간의 $f(P, S)$에 $w_A$를 더하면 된다. $A$ 오른쪽의 왼쪽 방향 센서를 $B(x_B, y_A)$라 하자. 이 구간은 $[x_A, x_B - 1]$이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$g(Q, S)$는 $x_S &amp;lt; x &amp;lt; x_Q$를 만족하는 각 $x$에 대해, $y \ge y_S$를 만족하는 위쪽 방향 센서들의 가중치 중 최댓값의 합이다. 서브태스크 6과 유사하게 이를 ($x &amp;lt; x_Q$를 만족하는 각 $x$에 대해, $y \ge y_S$를 만족하는 위쪽 방향 센서들의 가중치 중 최댓값의 합) $-$ ($x \le x_S$를 만족하는 각 $x$에 대해, $y \ge y_S$를 만족하는 위쪽 방향 센서들의 가중치 중 최댓값의 합)으로 처리하자. 이제 $x \le x_S, y \ge y_S$인 영역은 $S$에 배정할 수 있다. $x &amp;lt; x_Q$인 영역에서는 $y \ge y_S$를 만족하는 센서들 중 가장 $y$좌표가 작은 센서가 우리가 원하는 센서이다. $y$좌표를 올리며 위쪽 방향 센서 $A(x_A, y_A)$를 만난 경우, $A$ 위쪽의 위쪽 방향 센서를 $B(x_A, y_B)$라 하자. $x$좌표 구간 $[x_A + 1, N]$의 $g(Q, S)$에 $w_B - w_A$를 더하면 된다. $B$가 존재하지 않을 경우 $w_B = 0$으로 취급한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 $y$좌표에서 여러 센서가 존재할 경우, 위쪽 방향 센서들을 먼저 순회하며 각 $S$에 대한 최댓값을 구한 후, 다음 $y$좌표로 넘어가기 위해 $f(P, S)$와 $g(Q, S)$들을 업데이트해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 같은 $x$좌표를 공유하는 $P$와 $Q$들이 있을 수 있다. 세그먼트 트리에서는 각 좌표마다 하나의 센서만을 나타내야 하므로, 적절한 순서를 통해 서로 다른 좌표를 배정해야 한다. 같은 $x$좌표 내에서는 오른쪽 방향 센서에 더 작은 좌표를 배정해야 $x_P = x_Q$인 경우에 대한 처리가 가능함에 유의하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 $R$이 고정된 경우의 최댓값을 $O(N \log N)$에 구할 수 있어, 전체 문제를 $O(N^2 \log N)$에 해결할 수 있다.&lt;/p&gt;</description>
      <category>PS</category>
      <author>moonrabbit2</author>
      <guid isPermaLink="true">https://moonrabbit2.tistory.com/6</guid>
      <comments>https://moonrabbit2.tistory.com/6#entry6comment</comments>
      <pubDate>Thu, 16 Jun 2022 13:06:44 +0900</pubDate>
    </item>
    <item>
      <title>210713 팀연습</title>
      <link>https://moonrabbit2.tistory.com/5</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2036&quot; data-origin-height=&quot;1243&quot; data-filename=&quot;210713_scoreboard.PNG&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AcD5b/btq9Gsl5R7s/HvIMEXKhvlHmSguShcdKJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AcD5b/btq9Gsl5R7s/HvIMEXKhvlHmSguShcdKJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AcD5b/btq9Gsl5R7s/HvIMEXKhvlHmSguShcdKJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAcD5b%2Fbtq9Gsl5R7s%2FHvIMEXKhvlHmSguShcdKJ0%2Fimg.png&quot; data-origin-width=&quot;2036&quot; data-origin-height=&quot;1243&quot; data-filename=&quot;210713_scoreboard.PNG&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대회 링크: &lt;a href=&quot;https://codeforces.com/gym/102893&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://codeforces.com/gym/102893&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀연습도 안하면 PS 절대 안 할 것 같아서 팀연습을 고등학생 시절에 대충 몇 번 했던 것 이후로 처음 해 봤다. 처음에는 정신 차리려고 매운맛 대회로 하려 했는데, 쫄아서 적당히 쉬워보이는 셋을 들고 왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;초반부: 09:00~10:30 (00:00~01:30)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ABCD/EFGH/IJKL로 문제를 분배해서 보기로 했다. retro3014가 ABCD, 내가 EFGH, gs18115가 IJKL을 맡았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;F가 단순 조건문 문제임을 바로 발견했고, 00:04:52에 A AC가 나왔다. 그런데 내가 조건문 오타+복붙 실수까지 해 버리면서 브론즈 4따리 문제에 2틀을 박아버렸다.. 아무튼 00:07:12에 F AC를 받았다. 이후 EGH중 H는 정말 귀찮은 케이스 분석 문제로 보였고, G는 간단한 mcmf 문제로 보였다. 그래서 G를 잠시 고민해 봤는데 아니였다. 다시 보니 G는 그뭔씹 문제로 보였고, 그나마 E가 할만해 보여서 E를 잡았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 2틀을 또 적립하면서 00:19:28에 J AC가 나왔다. 그리고 30분 즈음에 내 E 풀이가 불완전하다는 것을 깨닫고 던졌다. 동시에 사용하면 안 되는 소파들끼리 간선을 이어 그래프를 만드는 풀이였는데, 결과적으로 접근 방식은 같지만 그래프의 형태에 대한 추측이 약간 틀렸었다. 나는 처음에 이분그래프라 생각했는데 코딩하면서 보니 생각하지 못했던 케이스가 있어서 던졌다. gs18115가 K를 해보라고 했는데, 문제를 읽어 보니 constructive라서 1초도 고민 안하고 걸렀고, I도 해보라 했는데 기하 인터렉티브라길래 또 걸렀다. 결국 귀찮아서 나중에 잡으려던 H로 넘어갔다. 대충 가능한 xx..x꼴 위치+x값을 잡고 경우의 수를 세면 될 것이라고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 00:34:03에 D AC가 나왔다. 48분 즈음에 gs18115가 L을 찍어봤지만 어림도 없었고, 이후 retro3014가 B를, gs18115가 C를 잡기로 했다. 나는 54분에 H 코딩을 끝냈지만 예제도 안나와서 디버깅해봤더니 정말 어림도 없는 풀이였다는 것을 깨달았다. 이후 BOJ 10802같은 DP를 이용해 주어진 범위 내의 수만 고려하는 식의 풀이가 가능해 보였고, 5차원 DP-&amp;gt;4차원 DP-&amp;gt;3차원 DP-&amp;gt;4차원 DP로 무한으로 즐기면서 풀이를 만들어냈다. 그 사이에 각각 01:06:39에 B AC가, 01:08:07에 C AC가 나왔다. B는 3틀 하면서 조금 고통받은 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 1시간 22분에 H를 냈지만 WA on test 3이 떴고, 풀이에 이어서 디버깅까지 무한으로 즐기기 시작했다. gs18115도 K에 적당히 믿음을 가지고 짠 코드를 계속 냈지만 계속 WA가 나왔다. 이후 함게 H 디버깅을 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;중반부: 10:30~11:30 (01:30~02:30)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;retro3014가 L을 쭉 잡다가 던지고 G가 mcmf 아니냐고 했고, 내가 그럴 것 같았는데 잘 모르겠다고 했다. 11시 즈음에 내가 DP는 맞게 짜 놓고 멍청하게 테케 문제에서 초기화를 제대로 안 한 것을 깨달았다. 바로 고쳐서 내봤는데 TLE가 났다. DP 차원을 하나 줄여야 하나 생각했고, 꽤 당황했다. 비슷한 시점에 gs18115가 문제를 찾았는데, 이미 TLE를 받고 난 뒤였다. gs18115가 차원을 줄이는 대신 누적합+바텀업으로 짜라고 했는데, 누적합은 쓸 곳을 못 찾았고 바텀업으로 재귀를 없애고 낸 코드는 더 앞쪽 테케에서 TLE가 났다. 이후 long long을 int로 바꿨는데 같은 테케에서 TLE가 났다. 결국 차원을 줄여야겠다고 생각해 고민해봤는데, 생각보다 많이 어려웠다. 그러다 재귀 DP가 더 빨랐는데 바텀업 코드만 int로 바꿔서 냈다는 것이 생각이 났고, 혹시나 해서 재귀 DP 코드도 int로 바꿔서 내 봤는데 예상치 못한 AC가 나왔다. 02:17:25에 H AC.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gs18115가 I가 주어진 간선을 포함하는 triangulation을 찾으면 된다고 했는데, 그 시점에서는 잘 생각이 안 났다. 그런데 gs18115가 모든 triangulation의 간선 수가 같은 것 같다고 한 말을 보자 GCJ 2021 Round 3 문제가 불현듯 생각이 났다. 정확히 저 문구를 풀이에서 본 것이 기억이 났다. 대충 링크 던져주면서 3N-3-(컨벡스 헐 위 점 개수)임을 알려줬다. retro3014는 K를 잡기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 I는 그냥 계속 가능한 간선을 찾으면 된다는 결론이 나왔고, 내가 코딩을 하려 했는데 뇌정지가 와서 풀이를 O(N^4)에서 줄일 수가 없었다. K는 dfs tree와 bfs tree 얘기가 나왔는데, 문제만 읽고 전혀 고민을 안 해서 그 얘기가 왜 나오나 싶었다. 그리고 gs18115와 함께 I를 고민했는데, 둘 다 뇌정지를 벗어나지 못하고 O(N^4)에서 줄이질 못했다. 그러다 내가 O(N^3) 풀이가 생각이 났는데, 확실히 맞나 고민하다 뇌 속에서 O(N^4)라는 결론을 내려버렸다. 결과적으로는 O(N^3) 풀이가 맞았고, 다행히 2분 쯤 지난 2시간 27분 즈음에 K를 한 번 틀리고 온 gs18115가 같은 풀이를 뇌정지 없이 생각해내서 코딩을 시작했다. 나는 다시 E와 G를 고민해보기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;후반부: 11:30~12:38 (02:30~03:38)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I는 코딩은 복잡한 문제는 아니였고, 02:44:07에 I AC가 나왔다. 이후 gs18115와 retro3014는 L을 토론했는데, retro3014가 자신이 한 관찰들을 말해줬다. W/2 기준으로 물건을 나누는 것과, 가치/무게 순으로 정렬해서 그리디하게 하는 관찰을 말했는데, 풀이를 보면 알겠지만 여기까지 오면 다 온거다ㅋㅋㅋ 그 사실을 깨달은 gs18115가 L을 풀기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 별개로 G를 잡고 있었는데, 온갖 플로우 그래프를 만들어보는 뇌정지 끝에 마음속에서 정해로 풀 수 없는 문제라고 결정하고 무지성 simplex 코드를 내 봤지만 어림도 없었다. 나중에 보니 simplex를 돌리되 integer 조건을 강제하기 위해 잘 재귀함수를 짜서 여러번 simplex를 돌리는 식으로 푼 팀들이 있었는데, 공부가 필요할 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 제출 후 약 1분 뒤인 02:55:13에 gs18115가 L AC를 받았다. 이후 E에 대해 잠시 토론을 했는데, retro3014가 플로우 아니냐고 했는데, 내가 n, m이 너무 크다고 했고, 내가 그래프를 만드는 식의 접근을 했다고 했다. 그런데 gs18115가 갑자기 풀이가 생각났다고 했다. 그런데 결과 출력을 위해 값을 바꾸는 방법을 처음에 생각하지 못했는데, 왼쪽 위부터 그냥 채우는 방식이 되냐고 물었는데 내가 된다고 했다. E 풀이가 완성됐고, gs18115는 E를 짜기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정신 차리고 보니 G는 모든 a_i값이 1이면 general weighted matching 문제랑 다를 게 없단 것을 깨달았다. 이 시점에서 플로우 쪽의 풀이는 아닐 것이라고 생각했다. 그리고 조금 더 고민해보니, 그냥 각 i마다 a_i 만큼의 정점을 만들어 주면 general weighted matching 문제가 된다는 것을 깨달았다. 더불어민규당 팀노트에서 열심히 베꼈고, 예제를 돌려봤는데 답이 나오지 않았다. minimum이 아닌 maximum을 구한 것이다. 그리고 무지성으로 모든 weight를 음수로 바꿨고, 당연히 0이 나왔다. 이후 뇌정지가 잠시 왔는데, matching의 크기가 항상 고정이라 모든 weight를 inf-weight로 바꾸면 된다는 것을 깨달았다. 이 부분까지 수정을 해서 제출했고, 03:16:57에 G AC를 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 E와 K 중 E는 풀이가 확실히 나온 것 같아서 K를 잡기로 했다. retro3014는 이미 K를 짜고 있는 중이었고, 나는 첫 WA 코드부터 보기 시작했다. 그러다 03:37:24에 E AC가 나왔다. 이제 K만 남았다고 생각하고 E 풀이에 대해 잠시 얘기하고 있었는데, retro3014가 K를 맞아왔다! 03:38:01에 K AC. 3컴의 힘으로 굉장히 빠른 시간에 올솔브를 할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;후기&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예상보다는 뒷쪽 문제가 많이 어려웠다. 중반부에 고통을 굉장히 많이 받았는데, 중후반부에 어려운 문제들을 빠르게 해결해서 결과적으로는 올솔브를 할 수 있었다. 3컴 아니었으면 못했을지도 모르겠다. 또 올솔해서 기분은 좋지만 패널티 관리가 심각하게 안 됐다. 그것도 3컴으로.. 아무 생각 없이 제출하지 말자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그와는 별개로 다 잘하는데 특히 자료구조를 매우 잘 하는 팀원(gs18115), 아이디어성 문제에 강한 팀원(Retro3014), 자료구조를 적당히 잘 하고 문자열/기하를 할 수 있고 이상한 사전지식들을 많이 아는 팀원(moonrabbit2)로 어느 정도 역할을 분배했었는데, 이상적으로 풀린다면 굉장히 안정적인 팀이라고 생각했다. 그리고 이번 대회에서는 이 분배에 굉장히 충실하게 따른 것 같고, 각자의 역할을 잘 해준 것 같아서 패널티와는 별개로 굉장히 기분이 좋다ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 나는 F와 H에서 심각하게 트롤을 했고, G도 결국은 나는 G 풀이를 팀노트 없이는 짤 수 없는 굉장한 날먹 풀이로 짰고 팀원들이 충분히 생각할 만한 풀이라고 느껴서 개인적으론 못했다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여담으로, G의 경우 공식 풀이는 지수 항이 들어가지만 mcmf만으로 해결했는데 풀이가 굉장히 재밌다. 한 번씩 읽어보는 것을 추천한다.&lt;/p&gt;</description>
      <category>PS</category>
      <author>moonrabbit2</author>
      <guid isPermaLink="true">https://moonrabbit2.tistory.com/5</guid>
      <comments>https://moonrabbit2.tistory.com/5#entry5comment</comments>
      <pubDate>Thu, 15 Jul 2021 06:47:38 +0900</pubDate>
    </item>
    <item>
      <title>백준 출제한 문제 풀이 요약</title>
      <link>https://moonrabbit2.tistory.com/4</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;너무 오랫동안 여길 방치한 것 같고, 풀이를 올리지 않은 문제도 있길래 각 문제당 간단한 풀이 요약을 올린다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15352 욱제와 그의 팬들&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;연속된 같은 팬클럽인 사람을 Union-Find로 관리하자. 한명이 빠지면 그 구간의 크기가 1 감소하고, 구간의 길이가 1이였으면 양옆의 구간이 합쳐질 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15560 15561 구간 합 최대?&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;흔히 금광 세그라고 불리는 구간합 최댓값 세그먼트 트리를 사용하면 된다. 왼쪽 부분합의 최댓값, 오른쪽 부분합의 최댓값, 구간합의 최댓값, 구간의 합을 노드에 저장하면 잘 합쳐진다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15562 네트워크&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;각 정점에서 출발하는 경로의 개수를 생각하면 답의 하한은 쉽게 추측할 수 있다. 직관적으로 충분할 것이라 예상할 수 있고, 실제로 그렇다. 나에게로 오는 간선은 위상정렬 상에서 내 앞에서 온다는 점을 생각하면 항상 들어가는 경로 개수가 부족할 일이 없게 할 수 있단 것을 알 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15563 15564 &amp;Auml;ventyr&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;대회 당시 멍청한 내가 의도한 풀이는 HLD였고, 실제로는 센트로이드 트리를 이용해서 푸는 것이 대중적인 풀이로 보인다. 두 풀이 모두 D(u)를 u가 루트인 서브트리에서 u에서 바이올린으로 가는 최소 거리라고 정의한 후, 트리를 타고 올라가면서 dist(u,v)+D(u)의 최솟값을 구하는 방법을 사용한다. 센트로이드 트리에서는 높이가 낮으니 일반적인 방법으로 하면 되고, HLD 풀이는 lazy propagation이 필요한데, lazy 값 f는 값 x를 가진 [l,r] 노드를 min(x,f-2*r)로 바꿔준다. 정확히는 min(x,f-2*l,...,f-2*r)인데, 두 값은 당연히 동일하다. 그냥 D(u)값을 관리하는 것이 아니라, D(u)-h(u)를(h는 chain 상에서 깊이) 관리해야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15565 귀여운 라이언&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;two pointer/inchworm/sliding window 기본 연습문제다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15566 15567 15568 개구리&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;선호하는 연꽃이 2개 이하라는 점에서 2-SAT이 떠올려진다. 조건들은 어렵지 않고, 조건 간선을 만들때 시간복잡도에 문제가 생기지 않게 구현해야 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15569 15570 15571 15572 블록&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;DP식 자체는 굉장히 흔한 유형이고, 어렵지 않게 계산할 수 있다. 초기항들 계산은 반복문으로 찾고, 나머지는 키타마사법을 이용해 빠르게 구할 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15573 채굴&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이분 탐색+BFS를 하거나 다익스트라의 변형 느낌으로 우선순위 큐를 사용해도 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15574 15575 신호&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;가능한 모든 x좌표를 사용해야 함은 삼각부등식으로 어렵지 않게 보일 수 있다. 같은 x좌표 안에서 맨 위와 아래만 사용해도 된다는 것은 더 어렵지만 여전히 삼각부등식으로 보일 수 있다. 이제 정렬 후 x좌표의 구간들을 찾고, 현재 x좌표 기준 위/아래에 도달하는 최대 길이를 DP로 저장하면 된다. 지그재그 형태의 경로가 최적이라 추측할 수 있는데, 아니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15646 농부 후안은 바리스타입니다&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;2D펜윅 연습문제다. 일반적인 점 업데이트-구간 쿼리가 아니라 반대인데, 결국 한 쿼리에서 2D 부분합을 구하는 것임을생각하면, 부분합이 곧 자신의 값이 되게 업데이트를 4번 해서 만들 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15647 로스팅하는 엠마도 바리스타입니다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;아무 정점에서 답을 구한 후, 인접한 정점으로 옮기면서 답이 얼마나 변하는지를 관찰하면, DP로 전처리하면 그 값을 구할 수 있음을 알 수 있다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15648 추출하는 폴도 바리스타입니다&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째 조건은 쉽다. 두 번째 조건도 구간 쿼리고, 어렵지 않다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15896 &amp;amp;+ +&amp;amp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;amp;+는 쉽다. i번째 비트가 켜져있는 수의 개수를 저장하면 된다. +&amp;amp;는 어렵다. i번째 비트가 켜져있을 조건이 모든 합이 2^(i+1)로 나눈 나머지가 두 구간중 하나에 포함되어야 함을 알면 다양한 풀이가 가능하다.&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;15901 소각로&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;재미없는 자료구조 연습문제이다. 대기열의 관리를 데크로 하고 종류를 세그먼트 트리/set으로 관리하는 방법이 있고, 대기열의 관리를 set으로 하고 번호를 세그먼트 트리로 관리하는 방법이 있다. 시간 측면이나 응용가능성 측면이나 앞 풀이가 더 좋아보인다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;16217 옥토끼나라&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;트리면 매우 쉬운 DP 문제다. 그래프로 바뀌면서 DFS 트리 상의 back edge가 추가되었다. 그 경우 위의 연결 컴포넌트와 합쳐진단 것을 고려하면, 위의 컴포넌트만 따로 관리하면 비슷하게 해결 가능하다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;16219 정렬하기&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;답이 항상 0 또는 -1일꺼라 생각할 수 있지만, 반례가 하나 있다. 증명 과정을 다시 살펴보자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;16220 회의&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;될것만 같은 그리디가 실제로 된다. 데이터가 약해서 이상한 그리디로도 맞을 것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;16223 클러스터&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Dynamic CHT를 세그먼트 트리의 노드로 만들면 된다. 리더 회사가 왼쪽인지 오른쪽인지에 따라 관리 방법이 다른데, 오른쪽이면 구간 쿼리 점 업데이트, 왼쪽이면 구간 업데이트 점 쿼리다. CHT를 lazy를 한다는 끔찍한 생각은 필요없고, 점 쿼리임을 이용하면 구간 업데이트를 할 때 노드들만 업데이트하고 점 쿼리를 리프까지 파고들면서 방문한 노드마다 쿼리를 날리면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;16231 내가 그린 라이언 그림&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;멍청하게 smaller to larger 테크닉을 쓰면 털린다. 답에서 빠졌다가 다시 들어오는 경우가 있기 때문이다. 이 경우가 O(N)번 발생한다는 것을 증명한 후 현재 답 집합과 후보 집합을 관리하면 된다. 개수 조건만 유지한 채 세그먼트 트리 등으로 값을 관리해줘도 된다. 두 번째 풀이의 경우 정점마다 여러 쿼리를 물을 수 있다는 장점이 있지만, 세그먼트 트리로 관리하는 방법은 메모리에 추가로 로그가 붙는다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;16233 수학 문제&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;식을 써보면 진법처럼 하는 방법이 가능함이 증명 가능하다. 이외에도 다양한 방법이 가능하고, X의 자릿수 합을 100000으로 나눈 몫과 나머지를 각각 이용해 전처리 후 O(1)에 구하는 방법이 재미있었다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17093 Total Circle&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;초심자를 위한 문제. 더 빠르게 해결도 가능하지만 너무 힘들다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17094 Serious Problem&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;쉽다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17095 Min-Max Subsequence&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;Subarray라 쓰지 않은 이유는 도저히 모르겠다. lower_bound 등을 활용해 O(NlogN)에 푼 사람이 많지만, 현재 기준 앞의 가장 오른쪽의 최솟값과 최댓값의 위치를 가지고 있으면 O(N)에도 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17096 Tourist&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;최단경로 DAG를 생각해보면, 각 정점마다 나에게 오는 간선 중 하나는 이용해야 하며, 하나만 이용해도 된다. 그리고 그 하나는 비용이 최소인 간선일 때 최적이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17097 Truth Tellers&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;i가 가능할 조건은 Ai &amp;lt;= i &amp;lt;= Bi인 사람이 i명 이상인 것이다. Vi를 Ai &amp;lt;= i &amp;lt;= Bi인 사람의 수 - i라 정의하자. 구간에 1을 더하고 빼면서 V값이 0 이상인 가장 큰 인덱스를 찾는 문제가 되고, 세그먼트 트리에 lazy propagation과 함께 세그먼트 트리에서 이분탐색하는 테크닉을 이용하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17098 Boomerangs&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;DFS트리에서 열심히 케이스 분석을 하자. back edge만 2개쓰는 경우는 의미가 없다. 한 간선이 절선이면 반드시 가능하니 먼저 세주자. 이제 각 정점 u에서 자신의 부모로 가는 간선이 사용된 부메랑의 개수를 셀 것이다. 이 간선이 절선이면 당연히 넘어간다. u의 서브트리에서 u 위로 가는 back edge가 1개뿐이고, 이 간선의 끝점이 u 또는 u의 부모인 것이 유일한 tree edge-back edge케이스다. 두 간선이 모두 tree edge인 경우는 좀더 귀찮은데, 자식 v로 가는 간선을 추가로 사용한다 하자. 마찬가지로 이 간선이 절선이면 넘어간다. 이제 v의 서브트리에서 u로 가는 back edge가 없고, 다른 자식 w의 서브트리에서 u 위로 가는 경우가 없어야 한다. v에서 u로 가는 back edge가 없다면 u 위로 가는 것이 반드시 있기 때문이다(절선이 아니므로). 꽤 다양한 값을 계산해야 하는데, dfs 과정을 생각해보면 대부분은 어렵지 않게 구할 수 있다. 이 외에도 다양한 풀이가 존재하는 것 같다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17099 Contest&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;꽤 다양한 방법의 DP 풀이가 있다. 내 풀이는 현재 아직 끝나지 않은 대회들을 우선순위 큐로 관리하는 것이다. 우선순위 큐에서 뺄 때는 현재 시작점이 끝점보다 뒤에 있을 때이고, 그 때 현재까지 DP값들 중 최댓값을 갱신해주면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17100 Candy Boxes&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;냅색 문제의 응용이다. 전 포스트에서 올렸던 방식과 비슷하게 데크를 이용한 최적화를 사용하면 된다. STL을 쓰면 안타깝게도 TLE가 날 수 있다. 이러고 싶지 않았는데 펜윅이 너무 빨랐다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17101 Dynamic Centroid&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;센트로이드가 정점이 하나 붙여지면 최대 거리 1만큼 이동함은 직관적이고 증명도 어렵지 않다. 움직이는 방향은 새 정점 방향이어야 하고, 센트로이드 기준 부모 방향인지는 dfs ordering으로 서브트리 안에 포함되어 있는지를 확인하면 되고, 자식 방향이면 새 정점에서 (거리-1)만큼 부모로 가거나, 센트로이드에서 자식들의 dfs ordering을 저장해놓은 뒤, lower_bound 등으로 해당하는 자식을 찾는 방법이 있다. 실제로 이동해야 하는지는 dfs ordering을 이용한 세그먼트 트리로 서브트리의 정점 개수를 구하면 된다. HLD로도 되는데, 그러지 말자.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17102 Grid Query&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;부분합이 어떻게 변화하는지를 관찰하면 함수들의 합으로 나타낼 수 있으므로, &lt;span style=&quot;color: #333333;&quot;&gt;스위핑을 섞으면서&amp;nbsp;&lt;/span&gt;각 계수들을 세그먼트 트리를 이용해 관리해주면 된다. 관리할 부분합이 2D 부분합인지, 행별 부분합의 구간합인지에 따라 조금은 디테일에 차이가 있고, 어느 방법이든 상관없을 것이다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17365 별다줄&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;naive한 DP는 시간이 너무 오래걸린다. 문자열의 축약 후보들을 i가 이동함에 따라 트라이에서 이동시키면서 관리하면 된다는 것을 관찰하면 된다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;17376 룰렛&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;시작점과 끝점을 잇는 경로 상의 정점들을 반드시 모두 지나고, 순서대로 지나기 때문에, 결국은 자기에서 시작해 한번 이상 인접한 정점으로 이동할 확률, 자기에서 시작해 자기에서 끝나는 확률들을 구하면 된다. 이 값들은 그리 직관적이진 않지만 무한등비급수를 구하는 방법을 이용해 구할 수 있다. 이후에는 경로 곱 쿼리고, 다양한 방법으로 처리가 가능하다. 나는 LCA만 구하고 부분곱+역원으로 했고, LCA를 구하면서 구간곱 스파스 테이블을 함께 사용해도 된다.&lt;/p&gt;</description>
      <category>PS</category>
      <author>moonrabbit2</author>
      <guid isPermaLink="true">https://moonrabbit2.tistory.com/4</guid>
      <comments>https://moonrabbit2.tistory.com/4#entry4comment</comments>
      <pubDate>Mon, 1 Jun 2020 22:11:34 +0900</pubDate>
    </item>
    <item>
      <title>기본적인 0/1 배낭 문제 및 그 변형</title>
      <link>https://moonrabbit2.tistory.com/3</link>
      <description>&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/12865&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;12895. 평범한 배낭&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size:11pt;&quot;&gt;평범 그 자체인 가장 기본적인 0/1 배낭 문제다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/992CF8485C2B56152D&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28dp%5Bi%5D%5Bj%5D%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;62&quot; height=&quot;19&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;를&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;i번 물건까지 사용할 수 있을 때, 무게 합이 j일 때의 최대 가치&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;라고 정의하자.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/99A1FC4C5C2B55FB2D&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28dp%5Bi%5D%5Bj%5D%3Dmax%28dp%5Bi-1%5D%5Bj%5D%2Cdp%5Bi-1%5D%5Bj-W%5Bi%5D%5C%5D%20+V%5Bi%5D%29%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;346&quot; height=&quot;19&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;가 되고, 어렵지 않게 해결할 수 있다. 시간복잡도는&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/99B911435C2B565E1A&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28O%28NK%29%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;53&quot; height=&quot;19&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14305&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;14305&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/14305&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;. Stretch Rope&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;0/1 배낭 문제에서 한 배낭의 무게가&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/9992094B5C2B57E027&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28%5BA_%7B%20i%20%7D%2CB_%7B%20i%20%7D%5D%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;57&quot; height=&quot;21&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;라는 범위로 표현되는 문제다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 14.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;마찬가지로&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/992CF8485C2B56152D&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28dp%5Bi%5D%5Bj%5D%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;62&quot; height=&quot;19&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;를&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;i번 물건까지 사용할 수 있을 때, 무게 합이 j일 때의 최소&amp;nbsp;가치&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;라고 정의해서 해결할 수 있다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;그냥 무작정 dp를 돌리면 시간복잡도가&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/99716F4F5C2B58402B&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28O%28TNL%5E%7B%202%20%7D%29%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;68&quot; height=&quot;21&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;이어서 시간 초과가 난다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;핵심 아이디어는 해당 물건을 사용해서 무게 합이 j가 되게 하려면, 기존 무게 합이&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/99A5084B5C2B58A628&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28%5Bj-B_%7B%20i%20%7D%2Cj-A_%7B%20i%20%7D%5D%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;84&quot; height=&quot;21&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;에 포함되어야 한다는 것이다. 이 구간은 j가 증가함에 따라 오른쪽으로 이동하는 구간이고, 고로 데크를 이용한 슬라이딩 윈도우로 구간 최솟값을 구하는 테크닉을 사용하면 시간복잡도를&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/99ED41485C2B58F12B&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28O%28TNL%29%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;62&quot; height=&quot;19&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;로 줄일 수 있&lt;/span&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/12920&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;12920. 평범한 배낭&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/12920&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt; 2&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 18pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size:11pt;&quot;&gt;이번에는 한 물건을&amp;nbsp;각 물건마다 주어진 한도 내에서 여러번 사용할 수 있다. 이런 문제를 0/K 배낭 문제라고 한다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size:11pt;&quot;&gt;가장 단순한 방법은 물건을 K개 만드는 방법이고, 시간복잡도는&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/997535425C2B59A61B&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28O%28NMK%29%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;67&quot; height=&quot;19&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;로 매우 느리다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;이 방법을 해결하는 첫 번째 방법은&amp;nbsp;굳이 K개를 다 만들 필요가 없단 것을 깨달으면 알 수 있는데, 2진법의 논리에서 생각을 해 본다면 K=12일때는 1개, 2개, 4개, 12-(1+2+4)=5개에 해당되는 물건들만 만들어도 1개부터 12개까지의 모든 방법을 표현할 수 있다는 것을 알 수 있다. 이 방법을 일반화하면 각 물건마다 logK개 만큼의 물건만 만들어도 되고, 시간복잡도는&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/99AEB23B5C2B5A8825&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28O%28NMlogK%29%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;90&quot; height=&quot;19&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;다.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;이 방법과는 완전히 다른 방법으로 접근한다면, 더욱 빠르게 이 문제를 해결할 수 있다. 이번 방법의 핵심은 어떠한 무게 합 j가 되게 하는 기존 무게 합은 W[i]로 나눈 나머지가 같다는 것이다. 결국, 우리는 W[i]로 나눈 나머지에 따라서 무게 합들을 나누어서 해결할 수 있다. W[i]로 나눈 나머지가 같은 무게 합들에 대해서, j가 될 수 있게 하는 무게 합들은 앞 K개의 무게 합들이다. 기존 무게 x의 W[i]로 나눈 나머지가 같은 무게 합들의 배열 상 위치를 p, j의 위치를 q라고 하자. x에서 j로 넘어간다면, dp값은&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/99DC36345C2B5C4119&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28dp%5Bi-1%5D%5Bx%5D+V%5Bi%5D%5Ctimes%20%28q-p%29%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;168&quot; height=&quot;19&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;이 되고, q에 의한 부분을 제외하면 x를 나타내는 값은&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/990B7C405C2B5DCA28&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28dp%5Bi-1%5D%5Bx%5D-V%5Bi%5D%5Ctimes%20p%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;139&quot; height=&quot;19&quot;&gt;&lt;span style=&quot;font-size: 11pt;&quot;&gt;로 일정하다. 결국 우리는 K칸 앞까지의 값들 중 최댓값을 알아야 하고, 이는 14305번처럼 데크를 이용한 슬라이딩 윈도우를 통해서 해결할 수 있다. 시간복잡도는&amp;nbsp;&lt;/span&gt;&lt;img class=&quot;txc-formula&quot; src=&quot;https://t1.daumcdn.net/cfile/tistory/99DB274B5C2B5C9B1B&quot; historydata=&quot;%3Cflashrichtext%20version%3D%221%22%3E%0A%20%20%3Ctextformat%20font%3D%22Dotum%22%20size%3D%2216%22%20color%3D%222236962%22%20bold%3D%22false%22%20italic%3D%22false%22%20underline%3D%22false%22%20url%3D%22%22%20target%3D%22transparent%22%20align%3D%22left%22%20leftMargin%3D%2225%22%20rightMargin%3D%2225%22%20indent%3D%220%22%20leading%3D%220%22%20blockIndent%3D%220%22%20kerning%3D%22true%22%20letterSpacing%3D%220%22%20display%3D%22block%22%3E%28O%28NM%29%29%3C/textformat%3E%0A%3C/flashrichtext%3E%2C%0A11%2C%0A0xFFFFFF&quot; width=&quot;55&quot; height=&quot;19&quot;&gt;이&lt;span style=&quot;font-size: 11pt;&quot;&gt;다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>PS</category>
      <author>moonrabbit2</author>
      <guid isPermaLink="true">https://moonrabbit2.tistory.com/3</guid>
      <comments>https://moonrabbit2.tistory.com/3#entry3comment</comments>
      <pubDate>Tue, 1 Jan 2019 21:28:06 +0900</pubDate>
    </item>
  </channel>
</rss>