Jekyll2021-05-05T10:11:16+00:00https://justicehui.github.io/rss/JusticeHui가 PS하는 블로그Let's solve problem with JusticeHui!JusticeHui백준19499 K-transform2021-04-19T21:45:00+00:002021-04-19T21:45:00+00:00https://justicehui.github.io/ps/2021/04/19/BOJ19499<h3 id="문제-링크">문제 링크</h3> <ul> <li>http://icpc.me/19499</li> </ul> <h3 id="사용-알고리즘">사용 알고리즘</h3> <ul> <li>FFT</li> <li>Kitamasa</li> <li>Fenwick Tree</li> </ul> <h3 id="시간복잡도">시간복잡도</h3> <ul> <li>$O(K \log K \log M)$</li> </ul> <h3 id="풀이">풀이</h3> <p>정확히 $T$번 연산해서 $N$이 되는 경우의 수를 $g(T, N)$라고 정의합시다. $g(T, N)$은 아래와 같이 표현할 수 있습니다.</p> \[g(T, N) = \begin{cases} 1 \text{, if } T = 0 \\ g(T-1, Nk) \text{, if } k \vert (N+1) \\ g(T-1, N+1) + g(T-1, Nk) \text{, otherwise} \end{cases}\] <p>입력으로 주어진 $k, m, mod$에 대해 $g(k, m) \mod mod$가 문제의 정답이 됩니다.</p> <p>여러 $k$에 대해 로컬에서 작은 항을 계산해본 뒤 berlekamp-massey를 돌려보면 선형 점화식을 얻을 수 있습니다. $D(m)$을 문제의 정답이라고 정의하면, 점화식은 아래와 같이 나옵니다.</p> \[D(m) = \begin{cases}2^m \text{, if } m &lt; k-1 \\ 2^m-1 \text{, if } m = k-1 \\ \displaystyle \sum_{i=1}^{k} D(m-i) \text{, otherwise}\end{cases}\] <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">lll</span> <span class="o">=</span> <span class="n">__int128_t</span><span class="p">;</span> <span class="kt">int</span> <span class="n">K</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">f</span><span class="p">(</span><span class="kt">int</span> <span class="n">T</span><span class="p">,</span> <span class="n">lll</span> <span class="n">N</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">T</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span> <span class="k">if</span><span class="p">((</span><span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="n">K</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="n">T</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="o">*</span><span class="n">K</span><span class="p">);</span> <span class="k">else</span> <span class="k">return</span> <span class="p">(</span><span class="n">f</span><span class="p">(</span><span class="n">T</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">f</span><span class="p">(</span><span class="n">T</span><span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="o">*</span><span class="n">K</span><span class="p">))</span> <span class="o">%</span> <span class="n">MOD</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Go</span><span class="p">(</span><span class="kt">int</span> <span class="n">_k</span><span class="p">){</span> <span class="n">K</span> <span class="o">=</span> <span class="n">_k</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">V</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">3</span><span class="o">*</span><span class="n">K</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">V</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">f</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span> <span class="k">auto</span> <span class="n">R</span> <span class="o">=</span> <span class="n">berlekamp_massey</span><span class="p">(</span><span class="n">V</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">K</span> <span class="o">&lt;</span> <span class="mi">10</span><span class="p">)</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">K</span> <span class="o">&lt;&lt;</span> <span class="s">" : "</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">R</span><span class="p">)</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">i</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <p>$k \leq 10^4, m \leq 10^{18}$이므로 Kitamasa와 FFT를 사용하면 $O(k \log k \log m)$에 점화식을 계산할 수 있습니다.<br /> 하지만, FFT를 사용한 다항식 나눗셈은 <strong>느린</strong> $O(k \log k)$에 속하기 때문에 2초라는 빡빡한 시간 제한을 통과하기 어렵습니다. 최적화를 해야 합니다.</p> <p>Divisor를 보면, 항상 $C_k(x) = x^k - x^{k-1} - x^{k-2} - x^{k-3} - \cdots - 1$ 꼴이라는 것을 알 수 있습니다. 어떤 다항식을 $C_k(x)$로 나눈 나머지를 구하는 과정을 손으로 직접 계산해보면, 어떤 수 $c$를 적당한 구간 $[i-k, i-1]$에 더하는 연산을 여러 번 수행한다는 것을 알 수 있습니다. 우리는 이런 연산을 Fenwick Tree를 사용해 매우 빠르게 수행할 수 있습니다. 그러므로 다항식 나눗셈을 <strong>빠른</strong> $O(k \log k)$에 할 수 있고, AC를 받을 수 있습니다.</p> <h3 id="전체-코드">전체 코드</h3> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/****************************** Author: jhnah917(Justice_Hui) g++ -std=c++17 -DLOCAL -O3 -lm -mavx -mavx2 -mfma ******************************/</span> <span class="cp">#pragma GCC optimize("O3") #pragma GCC target("avx,avx2,fma") #include &lt;bits/stdc++.h&gt; #include &lt;smmintrin.h&gt; #include &lt;immintrin.h&gt; #define all(v) v.begin(), v.end() #define sz(v) (int)(v.size()) </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">int64_t</span><span class="p">;</span> <span class="k">using</span> <span class="n">poly</span> <span class="o">=</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="n">ll</span> <span class="n">M</span><span class="p">;</span> <span class="kt">int</span> <span class="n">K</span><span class="p">,</span> <span class="n">MOD</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">Norm</span><span class="p">(</span><span class="n">ll</span> <span class="n">v</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">v</span> <span class="o">&lt;</span> <span class="o">-</span><span class="n">MOD</span> <span class="o">||</span> <span class="n">v</span> <span class="o">&gt;=</span> <span class="n">MOD</span><span class="p">)</span> <span class="n">v</span> <span class="o">%=</span> <span class="n">MOD</span><span class="p">;</span> <span class="k">return</span> <span class="n">v</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="o">?</span> <span class="n">v</span> <span class="o">+</span> <span class="n">MOD</span> <span class="o">:</span> <span class="n">v</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Norm</span><span class="p">(</span><span class="n">poly</span> <span class="o">&amp;</span><span class="n">a</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="o">&amp;</span><span class="n">i</span> <span class="o">:</span> <span class="n">a</span><span class="p">)</span> <span class="n">i</span> <span class="o">=</span> <span class="n">Norm</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="k">while</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">a</span><span class="p">.</span><span class="n">back</span><span class="p">())</span> <span class="n">a</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span> <span class="p">}</span> <span class="kr">inline</span> <span class="kt">int</span> <span class="nf">Add</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">){</span> <span class="k">return</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="o">&gt;=</span><span class="n">MOD</span> <span class="o">?</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="o">-</span><span class="n">MOD</span> <span class="o">:</span> <span class="n">a</span><span class="o">+</span><span class="n">b</span><span class="p">;</span> <span class="p">}</span> <span class="kr">inline</span> <span class="kt">int</span> <span class="nf">Sub</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">){</span> <span class="k">return</span> <span class="n">a</span> <span class="o">&gt;=</span> <span class="n">b</span> <span class="o">?</span> <span class="n">a</span><span class="o">-</span><span class="n">b</span><span class="o">+</span><span class="n">MOD</span> <span class="o">:</span> <span class="n">a</span><span class="o">-</span><span class="n">b</span><span class="p">;</span> <span class="p">}</span> <span class="n">__m256d</span> <span class="nf">mult</span><span class="p">(</span><span class="n">__m256d</span> <span class="n">a</span><span class="p">,</span> <span class="n">__m256d</span> <span class="n">b</span><span class="p">){</span> <span class="n">__m256d</span> <span class="n">c</span> <span class="o">=</span> <span class="n">_mm256_movedup_pd</span><span class="p">(</span><span class="n">a</span><span class="p">);</span> <span class="n">__m256d</span> <span class="n">d</span> <span class="o">=</span> <span class="n">_mm256_shuffle_pd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="mi">15</span><span class="p">);</span> <span class="n">__m256d</span> <span class="n">cb</span> <span class="o">=</span> <span class="n">_mm256_mul_pd</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span> <span class="n">__m256d</span> <span class="n">db</span> <span class="o">=</span> <span class="n">_mm256_mul_pd</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span> <span class="n">__m256d</span> <span class="n">e</span> <span class="o">=</span> <span class="n">_mm256_shuffle_pd</span><span class="p">(</span><span class="n">db</span><span class="p">,</span> <span class="n">db</span><span class="p">,</span> <span class="mi">5</span><span class="p">);</span> <span class="n">__m256d</span> <span class="n">r</span> <span class="o">=</span> <span class="n">_mm256_addsub_pd</span><span class="p">(</span><span class="n">cb</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span> <span class="k">return</span> <span class="n">r</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">fft</span><span class="p">(</span><span class="kt">int</span> <span class="n">n</span><span class="p">,</span> <span class="n">__m128d</span> <span class="n">a</span><span class="p">[],</span> <span class="kt">bool</span> <span class="n">invert</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">){</span> <span class="kt">int</span> <span class="n">bit</span> <span class="o">=</span> <span class="n">n</span><span class="o">&gt;&gt;</span><span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(;</span><span class="n">j</span><span class="o">&gt;=</span><span class="n">bit</span><span class="p">;</span><span class="n">bit</span><span class="o">&gt;&gt;=</span><span class="mi">1</span><span class="p">)</span> <span class="n">j</span> <span class="o">-=</span> <span class="n">bit</span><span class="p">;</span> <span class="n">j</span> <span class="o">+=</span> <span class="n">bit</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">i</span><span class="o">&lt;</span><span class="n">j</span><span class="p">)</span> <span class="n">swap</span><span class="p">(</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">a</span><span class="p">[</span><span class="n">j</span><span class="p">]);</span> <span class="p">}</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">len</span><span class="o">=</span><span class="mi">2</span><span class="p">,</span> <span class="n">lv</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">len</span><span class="o">&lt;=</span><span class="n">n</span><span class="p">;</span> <span class="n">len</span><span class="o">&lt;&lt;=</span><span class="mi">1</span><span class="p">,</span> <span class="n">lv</span><span class="o">++</span><span class="p">){</span> <span class="kt">double</span> <span class="n">ang</span> <span class="o">=</span> <span class="mi">2</span><span class="o">*</span><span class="n">M_PI</span><span class="o">/</span><span class="n">len</span><span class="o">*</span><span class="p">(</span><span class="n">invert</span><span class="o">?-</span><span class="mi">1</span><span class="o">:</span><span class="mi">1</span><span class="p">);</span> <span class="n">__m256d</span> <span class="n">wlen</span><span class="p">;</span> <span class="n">wlen</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">cos</span><span class="p">(</span><span class="n">ang</span><span class="p">),</span> <span class="n">wlen</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">sin</span><span class="p">(</span><span class="n">ang</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span> <span class="o">+=</span> <span class="n">len</span><span class="p">){</span> <span class="n">__m256d</span> <span class="n">w</span><span class="p">;</span> <span class="n">w</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">w</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="n">len</span><span class="o">/</span><span class="mi">2</span><span class="p">;</span> <span class="o">++</span><span class="n">j</span><span class="p">){</span> <span class="n">w</span> <span class="o">=</span> <span class="n">_mm256_permute2f128_pd</span><span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="n">w</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">wlen</span> <span class="o">=</span> <span class="n">_mm256_insertf128_pd</span><span class="p">(</span><span class="n">wlen</span><span class="p">,</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="n">j</span><span class="o">+</span><span class="n">len</span><span class="o">/</span><span class="mi">2</span><span class="p">],</span> <span class="mi">1</span><span class="p">);</span> <span class="n">w</span> <span class="o">=</span> <span class="n">mult</span><span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="n">wlen</span><span class="p">);</span> <span class="n">__m128d</span> <span class="n">vw</span> <span class="o">=</span> <span class="n">_mm256_extractf128_pd</span><span class="p">(</span><span class="n">w</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">__m128d</span> <span class="n">u</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="n">j</span><span class="p">];</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">_mm_add_pd</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">vw</span><span class="p">);</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="n">j</span><span class="o">+</span><span class="n">len</span><span class="o">/</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">_mm_sub_pd</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">vw</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span><span class="p">(</span><span class="n">invert</span><span class="p">){</span> <span class="n">__m128d</span> <span class="n">inv</span><span class="p">;</span> <span class="n">inv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">inv</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mf">1.0</span><span class="o">/</span><span class="n">n</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">_mm_mul_pd</span><span class="p">(</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">inv</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int64_t</span><span class="o">&gt;</span> <span class="n">multiply</span><span class="p">(</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int64_t</span><span class="o">&gt;&amp;</span> <span class="n">v</span><span class="p">,</span> <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int64_t</span><span class="o">&gt;&amp;</span> <span class="n">w</span><span class="p">){</span> <span class="kt">int</span> <span class="n">n</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="k">while</span><span class="p">(</span><span class="n">n</span> <span class="o">&lt;</span> <span class="n">v</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">+</span><span class="n">w</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="n">n</span><span class="o">&lt;&lt;=</span><span class="mi">1</span><span class="p">;</span> <span class="n">__m128d</span><span class="o">*</span> <span class="n">fv</span> <span class="o">=</span> <span class="k">new</span> <span class="n">__m128d</span><span class="p">[</span><span class="n">n</span><span class="p">];</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">fv</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">fv</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">v</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">fv</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">w</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">fv</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">w</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">fft</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">fv</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span> <span class="o">+=</span> <span class="mi">2</span><span class="p">){</span> <span class="n">__m256d</span> <span class="n">a</span><span class="p">;</span> <span class="n">a</span> <span class="o">=</span> <span class="n">_mm256_insertf128_pd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">fv</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="mi">0</span><span class="p">);</span> <span class="n">a</span> <span class="o">=</span> <span class="n">_mm256_insertf128_pd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">fv</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">],</span> <span class="mi">1</span><span class="p">);</span> <span class="n">a</span> <span class="o">=</span> <span class="n">mult</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">a</span><span class="p">);</span> <span class="n">fv</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">_mm256_extractf128_pd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">fv</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">_mm256_extractf128_pd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="n">fft</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">fv</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int64_t</span><span class="o">&gt;</span> <span class="n">ret</span><span class="p">(</span><span class="n">n</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">n</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="n">ret</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int64_t</span><span class="p">)</span><span class="n">llround</span><span class="p">(</span><span class="n">fv</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span><span class="o">/</span><span class="mi">2</span><span class="p">);</span> <span class="k">delete</span><span class="p">[]</span> <span class="n">fv</span><span class="p">;</span> <span class="k">return</span> <span class="n">ret</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">tree</span><span class="p">[</span><span class="mi">1</span><span class="o">&lt;&lt;</span><span class="mi">15</span><span class="p">];</span> <span class="kt">void</span> <span class="nf">update</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="n">x</span><span class="o">+=</span><span class="mi">2</span><span class="p">;</span> <span class="n">x</span><span class="o">&lt;</span><span class="p">(</span><span class="mi">1</span><span class="o">&lt;&lt;</span><span class="mi">15</span><span class="p">);</span> <span class="n">x</span><span class="o">+=</span><span class="n">x</span><span class="o">&amp;-</span><span class="n">x</span><span class="p">)</span> <span class="n">tree</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">+=</span> <span class="n">v</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">query</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">){</span> <span class="kt">int</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="n">x</span><span class="o">+=</span><span class="mi">2</span><span class="p">;</span> <span class="n">x</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">;</span> <span class="n">x</span><span class="o">-=</span><span class="n">x</span><span class="o">&amp;-</span><span class="n">x</span><span class="p">)</span> <span class="n">ret</span> <span class="o">+=</span> <span class="n">tree</span><span class="p">[</span><span class="n">x</span><span class="p">];</span> <span class="k">return</span> <span class="n">ret</span><span class="p">;</span> <span class="p">}</span> <span class="n">poly</span> <span class="nf">mul</span><span class="p">(</span><span class="k">const</span> <span class="n">poly</span> <span class="o">&amp;</span><span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">poly</span> <span class="o">&amp;</span><span class="n">b</span><span class="p">){</span> <span class="k">auto</span> <span class="n">res</span> <span class="o">=</span> <span class="n">multiply</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span> <span class="n">Norm</span><span class="p">(</span><span class="n">res</span><span class="p">);</span> <span class="k">return</span> <span class="n">res</span><span class="p">;</span> <span class="p">}</span> <span class="n">poly</span> <span class="nf">rem</span><span class="p">(</span><span class="k">const</span> <span class="n">poly</span> <span class="o">&amp;</span><span class="n">a</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">K</span><span class="o">+</span><span class="mi">1</span> <span class="o">&gt;</span> <span class="n">a</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="k">return</span> <span class="n">a</span><span class="p">;</span> <span class="n">memset</span><span class="p">(</span><span class="n">tree</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span> <span class="n">tree</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">a</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">update</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]),</span> <span class="n">update</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">a</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&gt;=</span><span class="n">K</span><span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">){</span> <span class="kt">int</span> <span class="n">t</span> <span class="o">=</span> <span class="n">Norm</span><span class="p">(</span><span class="n">query</span><span class="p">(</span><span class="n">i</span><span class="p">));</span> <span class="n">update</span><span class="p">(</span><span class="n">i</span><span class="o">-</span><span class="n">K</span><span class="p">,</span> <span class="n">t</span><span class="p">);</span> <span class="n">update</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">-</span><span class="n">t</span><span class="p">);</span> <span class="p">}</span> <span class="n">poly</span> <span class="n">ret</span><span class="p">(</span><span class="n">K</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">K</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">ret</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">query</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="n">Norm</span><span class="p">(</span><span class="n">ret</span><span class="p">);</span> <span class="k">return</span> <span class="n">ret</span><span class="p">;</span> <span class="p">}</span> <span class="n">poly</span> <span class="nf">get</span><span class="p">(</span><span class="n">ll</span> <span class="n">k</span><span class="p">){</span> <span class="n">poly</span> <span class="n">d</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">},</span> <span class="n">xn</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">};</span> <span class="k">while</span><span class="p">(</span><span class="n">k</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">k</span> <span class="o">&amp;</span> <span class="mi">1</span><span class="p">)</span> <span class="n">d</span> <span class="o">=</span> <span class="n">rem</span><span class="p">(</span><span class="n">mul</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">xn</span><span class="p">));</span> <span class="n">k</span> <span class="o">&gt;&gt;=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">xn</span> <span class="o">=</span> <span class="n">rem</span><span class="p">(</span><span class="n">mul</span><span class="p">(</span><span class="n">xn</span><span class="p">,</span> <span class="n">xn</span><span class="p">));</span> <span class="p">}</span> <span class="k">return</span> <span class="n">d</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">K</span> <span class="o">&gt;&gt;</span> <span class="n">M</span> <span class="o">&gt;&gt;</span> <span class="n">MOD</span><span class="p">;</span> <span class="n">poly</span> <span class="n">D</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">pw</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">K</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">,</span> <span class="n">pw</span><span class="o">=</span><span class="n">Add</span><span class="p">(</span><span class="n">pw</span><span class="p">,</span> <span class="n">pw</span><span class="p">)){</span> <span class="k">if</span><span class="p">(</span><span class="n">i</span> <span class="o">&lt;=</span> <span class="n">K</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span> <span class="n">D</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">pw</span><span class="p">);</span> <span class="k">else</span> <span class="n">D</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">Sub</span><span class="p">(</span><span class="n">pw</span><span class="p">,</span> <span class="mi">1</span><span class="p">));</span> <span class="p">}</span> <span class="k">auto</span> <span class="n">C</span> <span class="o">=</span> <span class="n">get</span><span class="p">(</span><span class="n">M</span><span class="p">);</span> <span class="n">ll</span> <span class="n">ans</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">K</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">ans</span> <span class="o">+=</span> <span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">*</span> <span class="n">D</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="k">if</span><span class="p">(</span><span class="n">M</span> <span class="o">&lt;</span> <span class="n">K</span><span class="p">)</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">D</span><span class="p">[</span><span class="n">M</span><span class="p">];</span> <span class="k">else</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">Norm</span><span class="p">(</span><span class="n">ans</span><span class="p">);</span> <span class="p">}</span> </code></pre></div></div>JusticeHui문제 링크 http://icpc.me/19499백준10014 Traveling Saga Problem2021-04-16T21:02:00+00:002021-04-16T21:02:00+00:00https://justicehui.github.io/ps/2021/04/16/BOJ10014<h3 id="문제-링크">문제 링크</h3> <ul> <li>http://icpc.me/10014</li> </ul> <h3 id="사용-알고리즘">사용 알고리즘</h3> <ul> <li>Centroid</li> <li>트리 이진 변환</li> </ul> <h3 id="시간복잡도">시간복잡도</h3> <ul> <li>$O((N+Q) \log^2 N)$</li> </ul> <h3 id="풀이">풀이</h3> <p>어떤 정점에서 가장 먼 정점을 찾는 쿼리를 여러 번 수행하는 문제입니다. Centroid Decomposition을 이용하면 될 것 같다는 생각이 듭니다.</p> <p>입력으로 주어진 트리 $T$의 정점 $v$와 가장 멀리 떨어져있는 정점 $u$는, Centroid Tree $C_T$에서 $v$의 조상 $p$를 따라가면서 $p$의 $C_T$ 상에서의 자손을 보면 됩니다. 이때 $C_T$의 각 정점에서는, 그 서브 트리에 속하는 정점 $x$에 대해 $(Dist(p, x), x)$를 max heap으로 저장하고 있습니다.<br /> $u$는 $v$와 다른 서브트리에 속해야 하기 때문에, $v$의 $C_T$ 상의 조상 $p$의 자식 정점을 모두 순회해야 합니다.</p> <p>만약 트리가 성게 그래프(star graph)라면 Centroid Tree의 정점의 Degree가 $N-1$이 돼서 각 쿼리가 $O(N \log^2 N)$이 됩니다. 트리를 이진 트리로 바꿔주면 자식의 개수(정점의 Degree)가 최대 3이 되므로 각 쿼리를 $O(3 \log^2 N)$에 처리할 수 있습니다.</p> <h3 id="전체-코드">전체 코드</h3> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/****************************** Author: jhnah917(Justice_Hui) g++ -std=c++17 -DLOCAL ******************************/</span> <span class="cp">#include &lt;bits/stdc++.h&gt; #define x first #define y second #define all(v) v.begin(), v.end() #define compress(v) sort(all(v)), v.erase(unique(all(v)), v.end()) #define IDX(v, x) (lower_bound(all(v), x) - v.begin()) </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">uint</span> <span class="o">=</span> <span class="kt">unsigned</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">PII</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">SZ</span> <span class="o">=</span> <span class="mi">505050</span><span class="p">,</span> <span class="n">LG</span> <span class="o">=</span> <span class="mi">20</span><span class="p">,</span> <span class="n">INF</span> <span class="o">=</span> <span class="mh">0x3f3f3f3f</span><span class="p">;</span> <span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="n">pv</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">Inp</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">PII</span><span class="o">&gt;</span> <span class="n">G</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="kt">int</span> <span class="n">S</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">U</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">P</span><span class="p">[</span><span class="n">LG</span><span class="p">][</span><span class="n">SZ</span><span class="p">],</span> <span class="n">D</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">C</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="kt">int</span> <span class="n">CP</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">CID</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">priority_queue</span><span class="o">&lt;</span><span class="n">PII</span><span class="o">&gt;</span> <span class="n">Info</span><span class="p">[</span><span class="n">SZ</span><span class="p">][</span><span class="mi">4</span><span class="p">];</span> <span class="kt">void</span> <span class="nf">Flush</span><span class="p">(</span><span class="n">priority_queue</span><span class="o">&lt;</span><span class="n">PII</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">pq</span><span class="p">){</span> <span class="k">while</span><span class="p">(</span><span class="n">pq</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">U</span><span class="p">[</span><span class="n">pq</span><span class="p">.</span><span class="n">top</span><span class="p">().</span><span class="n">y</span><span class="p">])</span> <span class="n">pq</span><span class="p">.</span><span class="n">pop</span><span class="p">();</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">AddEdge</span><span class="p">(</span><span class="kt">int</span> <span class="n">s</span><span class="p">,</span> <span class="kt">int</span> <span class="n">e</span><span class="p">,</span> <span class="kt">int</span> <span class="n">x</span><span class="p">){</span> <span class="n">G</span><span class="p">[</span><span class="n">s</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span> <span class="n">G</span><span class="p">[</span><span class="n">e</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Rebuild</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">=-</span><span class="mi">1</span><span class="p">){</span> <span class="kt">int</span> <span class="n">lst</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">Inp</span><span class="p">[</span><span class="n">v</span><span class="p">]){</span> <span class="k">if</span><span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="n">b</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span> <span class="n">Rebuild</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">lst</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="n">AddEdge</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="n">lst</span> <span class="o">=</span> <span class="n">v</span><span class="p">;</span> <span class="k">else</span><span class="p">{</span> <span class="kt">int</span> <span class="n">dummy</span> <span class="o">=</span> <span class="o">++</span><span class="n">pv</span><span class="p">;</span> <span class="n">AddEdge</span><span class="p">(</span><span class="n">lst</span><span class="p">,</span> <span class="n">dummy</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">AddEdge</span><span class="p">(</span><span class="n">dummy</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">lst</span> <span class="o">=</span> <span class="n">dummy</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Init</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">=-</span><span class="mi">1</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">LG</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">][</span><span class="n">v</span><span class="p">]];</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">v</span><span class="p">]){</span> <span class="k">if</span><span class="p">(</span><span class="n">i</span><span class="p">.</span><span class="n">x</span> <span class="o">==</span> <span class="n">b</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span> <span class="n">P</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span><span class="p">;</span> <span class="n">D</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">D</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">C</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">+</span> <span class="n">i</span><span class="p">.</span><span class="n">y</span><span class="p">;</span> <span class="n">Init</span><span class="p">(</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">LCA</span><span class="p">(</span><span class="kt">int</span> <span class="n">u</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">D</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">D</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="n">swap</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="kt">int</span> <span class="n">diff</span> <span class="o">=</span> <span class="n">D</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">-</span> <span class="n">D</span><span class="p">[</span><span class="n">v</span><span class="p">];</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">diff</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">,</span> <span class="n">diff</span><span class="o">&gt;&gt;=</span><span class="mi">1</span><span class="p">)</span> <span class="k">if</span><span class="p">(</span><span class="n">diff</span> <span class="o">&amp;</span> <span class="mi">1</span><span class="p">)</span> <span class="n">u</span> <span class="o">=</span> <span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">u</span><span class="p">];</span> <span class="k">if</span><span class="p">(</span><span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">)</span> <span class="k">return</span> <span class="n">u</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">LG</span><span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="o">~</span><span class="n">i</span><span class="p">;</span> <span class="n">i</span><span class="o">--</span><span class="p">)</span> <span class="k">if</span><span class="p">(</span><span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">u</span><span class="p">]</span> <span class="o">!=</span> <span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">v</span><span class="p">])</span> <span class="n">u</span> <span class="o">=</span> <span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">u</span><span class="p">],</span> <span class="n">v</span> <span class="o">=</span> <span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">v</span><span class="p">];</span> <span class="k">return</span> <span class="n">P</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">u</span><span class="p">];</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">Dist</span><span class="p">(</span><span class="kt">int</span> <span class="n">u</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="k">return</span> <span class="n">C</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">+</span> <span class="n">C</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">-</span> <span class="mi">2</span><span class="o">*</span><span class="n">C</span><span class="p">[</span><span class="n">LCA</span><span class="p">(</span><span class="n">u</span><span class="p">,</span> <span class="n">v</span><span class="p">)];</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">GetSize</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">=-</span><span class="mi">1</span><span class="p">){</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">U</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span> <span class="o">!=</span> <span class="n">b</span><span class="p">)</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">+=</span> <span class="n">GetSize</span><span class="p">(</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="k">return</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">];</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">GetCent</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">tot</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">=-</span><span class="mi">1</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">U</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span> <span class="o">!=</span> <span class="n">b</span> <span class="o">&amp;&amp;</span> <span class="n">S</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">*</span><span class="mi">2</span> <span class="o">&gt;</span> <span class="n">tot</span><span class="p">)</span> <span class="k">return</span> <span class="n">GetCent</span><span class="p">(</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">tot</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="k">return</span> <span class="n">v</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Gather</span><span class="p">(</span><span class="kt">int</span> <span class="n">rt</span><span class="p">,</span> <span class="kt">int</span> <span class="n">id</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">,</span> <span class="kt">int</span> <span class="n">d</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">v</span> <span class="o">&lt;=</span> <span class="n">N</span><span class="p">)</span> <span class="n">Info</span><span class="p">[</span><span class="n">rt</span><span class="p">][</span><span class="n">id</span><span class="p">].</span><span class="n">emplace</span><span class="p">(</span><span class="n">d</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">U</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span> <span class="o">!=</span> <span class="n">b</span><span class="p">)</span> <span class="n">Gather</span><span class="p">(</span><span class="n">rt</span><span class="p">,</span> <span class="n">id</span><span class="p">,</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">d</span><span class="o">+</span><span class="n">i</span><span class="p">.</span><span class="n">y</span><span class="p">);</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">CD</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">=-</span><span class="mi">1</span><span class="p">){</span> <span class="kt">int</span> <span class="n">cent</span> <span class="o">=</span> <span class="n">GetCent</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">GetSize</span><span class="p">(</span><span class="n">v</span><span class="p">));</span> <span class="n">U</span><span class="p">[</span><span class="n">cent</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">CP</span><span class="p">[</span><span class="n">cent</span><span class="p">]</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span> <span class="kt">int</span> <span class="n">cnt</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">cent</span> <span class="o">&lt;=</span> <span class="n">N</span><span class="p">)</span> <span class="n">Info</span><span class="p">[</span><span class="n">cent</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">emplace</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">cent</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">cent</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">U</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">])</span> <span class="n">Gather</span><span class="p">(</span><span class="n">cent</span><span class="p">,</span> <span class="n">cnt</span><span class="o">++</span><span class="p">,</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">cent</span><span class="p">,</span> <span class="n">i</span><span class="p">.</span><span class="n">y</span><span class="p">);</span> <span class="n">cnt</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">cent</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">U</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">])</span> <span class="n">CID</span><span class="p">[</span><span class="n">CD</span><span class="p">(</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">cent</span><span class="p">)]</span> <span class="o">=</span> <span class="n">cnt</span><span class="o">++</span><span class="p">;</span> <span class="k">return</span> <span class="n">cent</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">Query</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="n">PII</span> <span class="n">mx</span><span class="p">(</span><span class="o">-</span><span class="n">INF</span><span class="p">,</span> <span class="o">-</span><span class="n">INF</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">v</span><span class="p">,</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">!=-</span><span class="mi">1</span><span class="p">;</span> <span class="n">j</span><span class="o">=</span><span class="n">CID</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="o">=</span><span class="n">CP</span><span class="p">[</span><span class="n">i</span><span class="p">]){</span> <span class="kt">int</span> <span class="n">c</span> <span class="o">=</span> <span class="n">Dist</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">k</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">k</span><span class="o">&lt;</span><span class="mi">4</span><span class="p">;</span> <span class="n">k</span><span class="o">++</span><span class="p">){</span> <span class="n">Flush</span><span class="p">(</span><span class="n">Info</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]);</span> <span class="k">if</span><span class="p">(</span><span class="n">j</span> <span class="o">==</span> <span class="n">k</span> <span class="o">||</span> <span class="n">Info</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">].</span><span class="n">empty</span><span class="p">())</span> <span class="k">continue</span><span class="p">;</span> <span class="k">auto</span> <span class="p">[</span><span class="n">d</span><span class="p">,</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">Info</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">].</span><span class="n">top</span><span class="p">();</span> <span class="n">mx</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">mx</span><span class="p">,</span> <span class="n">PII</span><span class="p">(</span><span class="n">d</span><span class="o">+</span><span class="n">c</span><span class="p">,</span> <span class="n">u</span><span class="p">));</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">mx</span><span class="p">.</span><span class="n">y</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="kt">int</span> <span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">s</span> <span class="o">&gt;&gt;</span> <span class="n">e</span><span class="p">;</span> <span class="n">Inp</span><span class="p">[</span><span class="n">s</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">e</span><span class="p">);</span> <span class="n">Inp</span><span class="p">[</span><span class="n">e</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">s</span><span class="p">);</span> <span class="p">}</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="o">+</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">G</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">reserve</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span> <span class="n">pv</span> <span class="o">=</span> <span class="n">N</span><span class="p">;</span> <span class="n">Rebuild</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="n">Init</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="n">CD</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="n">memset</span><span class="p">(</span><span class="n">U</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span> <span class="n">U</span><span class="p">);</span> <span class="kt">int</span> <span class="n">lst</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">U</span><span class="p">[</span><span class="n">lst</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">lst</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="n">lst</span> <span class="o">=</span> <span class="n">Query</span><span class="p">(</span><span class="n">lst</span><span class="p">);</span> <span class="n">U</span><span class="p">[</span><span class="n">lst</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">lst</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div>JusticeHui문제 링크 http://icpc.me/10014백준2598 기둥만들기2021-04-15T20:52:00+00:002021-04-15T20:52:00+00:00https://justicehui.github.io/koi/2021/04/15/BOJ2598<h3 id="문제-링크">문제 링크</h3> <ul> <li>http://icpc.me/2598</li> </ul> <h3 id="문제-출처">문제 출처</h3> <ul> <li>2004 KOI 초등부 3번</li> </ul> <h3 id="풀이">풀이</h3> <p>브루트포스를 열심히 하는 문제입니다.<br /> (1) 기둥의 상태를 잘 표현하는 것, (2) 회전했을 때 동일한 기둥인지 판별하는 것, (3) 정육면체의 상태를 잘 표현하는 것, 3가지를 어떻게 효율적으로 구현할지 고민해보는 것이 좋습니다.</p> <p>색이 4가지 종류 밖에 없기 때문에 각 색깔은 2비트로 표현할 수 있습니다. 옆면에 등장하는 16개의 면과 윗면까지 총 17개의 면을 표현해야 하므로 34비트가 필요합니다. 64bit 정수형으로 저장할 수 있습니다.</p> <p>회전했을 때 동일한 기둥인지 판별하는 것은, 옆면들의 minimum cyclic shift를 저장하면 됩니다. 다시 말해, 4개의 옆면을 회전시켰을 때 사전순으로 가장 앞서는 것만 저장하면 됩니다. (ex. <code class="language-plaintext highlighter-rouge">2031 / 0312 / 3120 / 1203</code> 중 <code class="language-plaintext highlighter-rouge">0312</code>만 저장)</p> <p>정육면체의 상태를 나타내는 것은 위/앞/오른쪽, 총 3개의 면을 고정하면 됩니다.</p> <p>위 3가지를 잘 조합하면 문제를 풀 수 있습니다.</p> <h3 id="전체-코드">전체 코드</h3> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/****************************** Author: jhnah917(Justice_Hui) g++ -std=c++17 -DLOCAL ******************************/</span> <span class="cp">#include &lt;bits/stdc++.h&gt; #define x first #define y second #define all(v) v.begin(), v.end() #define compress(v) sort(all(v)), v.erase(unique(all(v)), v.end()) </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">const</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;</span> <span class="n">SIDE</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span> <span class="p">{</span><span class="mi">5</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">3</span><span class="p">},</span> <span class="p">{</span><span class="mi">5</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">0</span><span class="p">},</span> <span class="p">{</span><span class="mi">5</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">1</span><span class="p">},</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">4</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">5</span><span class="p">},</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">},</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">}</span> <span class="p">};</span> <span class="n">string</span> <span class="n">A</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span> <span class="n">map</span><span class="o">&lt;</span><span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">3</span><span class="o">&gt;</span><span class="p">,</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;&gt;</span> <span class="n">mp</span><span class="p">;</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;</span> <span class="n">fst</span><span class="p">[</span><span class="mi">6</span><span class="p">];</span> <span class="kt">int</span> <span class="n">C_MAP</span><span class="p">[</span><span class="mi">256</span><span class="p">];</span> <span class="kr">inline</span> <span class="kt">int</span> <span class="nf">ID</span><span class="p">(</span><span class="kt">char</span> <span class="n">c</span><span class="p">){</span> <span class="k">return</span> <span class="n">C_MAP</span><span class="p">[</span><span class="n">c</span><span class="p">];</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Init</span><span class="p">(){</span> <span class="n">C_MAP</span><span class="p">[</span><span class="sc">'R'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">C_MAP</span><span class="p">[</span><span class="sc">'G'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">C_MAP</span><span class="p">[</span><span class="sc">'B'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="n">C_MAP</span><span class="p">[</span><span class="sc">'Y'</span><span class="p">]</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">6</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">3</span><span class="o">&gt;</span> <span class="n">a</span><span class="p">;</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;</span> <span class="n">b</span> <span class="o">=</span> <span class="n">SIDE</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">a</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">4</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">){</span> <span class="n">a</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">b</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span> <span class="n">a</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">b</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span> <span class="n">mp</span><span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">j</span><span class="p">)</span> <span class="n">fst</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span> <span class="n">rotate</span><span class="p">(</span><span class="n">b</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">b</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="p">.</span><span class="n">end</span><span class="p">());</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="n">ll</span> <span class="nf">Norm</span><span class="p">(</span><span class="n">ll</span> <span class="n">bit</span><span class="p">){</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">vec</span><span class="p">,</span> <span class="n">mn</span><span class="p">;</span> <span class="n">vec</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">bit</span> <span class="o">&amp;</span> <span class="mi">3</span><span class="p">);</span> <span class="n">bit</span> <span class="o">&gt;&gt;=</span> <span class="mi">2</span><span class="p">;</span> <span class="n">vec</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">bit</span> <span class="o">&amp;</span> <span class="mi">255</span><span class="p">);</span> <span class="n">bit</span> <span class="o">&gt;&gt;=</span> <span class="mi">8</span><span class="p">;</span> <span class="n">vec</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">bit</span> <span class="o">&amp;</span> <span class="mi">255</span><span class="p">);</span> <span class="n">bit</span> <span class="o">&gt;&gt;=</span> <span class="mi">8</span><span class="p">;</span> <span class="n">vec</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">bit</span> <span class="o">&amp;</span> <span class="mi">255</span><span class="p">);</span> <span class="n">bit</span> <span class="o">&gt;&gt;=</span> <span class="mi">8</span><span class="p">;</span> <span class="n">vec</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">bit</span> <span class="o">&amp;</span> <span class="mi">255</span><span class="p">);</span> <span class="n">bit</span> <span class="o">&gt;&gt;=</span> <span class="mi">8</span><span class="p">;</span> <span class="n">reverse</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">vec</span><span class="p">));</span> <span class="n">mn</span> <span class="o">=</span> <span class="n">vec</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">4</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="n">rotate</span><span class="p">(</span><span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">vec</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span><span class="o">+</span><span class="mi">4</span><span class="p">);</span> <span class="n">mn</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">mn</span><span class="p">,</span> <span class="n">vec</span><span class="p">);</span> <span class="p">}</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">4</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">bit</span> <span class="o">=</span> <span class="n">bit</span> <span class="o">&lt;&lt;</span> <span class="mi">8</span> <span class="o">|</span> <span class="n">mn</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">bit</span> <span class="o">=</span> <span class="n">bit</span> <span class="o">&lt;&lt;</span> <span class="mi">2</span> <span class="o">|</span> <span class="n">mn</span><span class="p">.</span><span class="n">back</span><span class="p">();</span> <span class="k">return</span> <span class="n">bit</span><span class="p">;</span> <span class="p">}</span> <span class="n">ll</span> <span class="nf">Check</span><span class="p">(</span><span class="k">const</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">b</span><span class="p">,</span> <span class="k">const</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">c</span><span class="p">,</span> <span class="k">const</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">d</span><span class="p">,</span> <span class="kt">int</span> <span class="n">top</span><span class="p">){</span> <span class="n">ll</span> <span class="n">ret</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">4</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="kt">int</span> <span class="n">bit</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">array</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span><span class="mi">4</span><span class="o">&gt;</span> <span class="n">now</span> <span class="o">=</span> <span class="p">{</span><span class="n">ID</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]]),</span> <span class="n">ID</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">]]),</span> <span class="n">ID</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="n">c</span><span class="p">[</span><span class="n">i</span><span class="p">]]),</span> <span class="n">ID</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">][</span><span class="n">d</span><span class="p">[</span><span class="n">i</span><span class="p">]])};</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">j</span> <span class="o">:</span> <span class="n">now</span><span class="p">)</span> <span class="n">bit</span> <span class="o">|=</span> <span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="n">j</span><span class="p">,</span> <span class="n">ret</span> <span class="o">|=</span> <span class="n">j</span><span class="p">,</span> <span class="n">ret</span> <span class="o">&lt;&lt;=</span> <span class="mi">2</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">bit</span> <span class="o">!=</span> <span class="mi">15</span><span class="p">)</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="n">ret</span> <span class="o">|=</span> <span class="n">top</span><span class="p">;</span> <span class="k">return</span> <span class="n">Norm</span><span class="p">(</span><span class="n">ret</span><span class="p">);</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">Init</span><span class="p">();</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">4</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">res</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">a</span> <span class="o">:</span> <span class="n">fst</span><span class="p">)</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">b</span> <span class="o">:</span> <span class="n">mp</span><span class="p">)</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">c</span> <span class="o">:</span> <span class="n">mp</span><span class="p">)</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">d</span> <span class="o">:</span> <span class="n">mp</span><span class="p">)</span> <span class="n">res</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">Check</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">c</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">d</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">ID</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="mi">3</span><span class="p">][</span><span class="n">d</span><span class="p">.</span><span class="n">x</span><span class="p">[</span><span class="mi">0</span><span class="p">]])));</span> <span class="n">sort</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">res</span><span class="p">),</span> <span class="n">greater</span><span class="o">&lt;&gt;</span><span class="p">());</span> <span class="k">while</span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">res</span><span class="p">.</span><span class="n">back</span><span class="p">())</span> <span class="n">res</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span> <span class="n">compress</span><span class="p">(</span><span class="n">res</span><span class="p">);</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">res</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="p">}</span> </code></pre></div></div>JusticeHui문제 링크 http://icpc.me/2598백준17823 수열과 쿼리 332021-04-05T05:40:00+00:002021-04-05T05:40:00+00:00https://justicehui.github.io/ps/2021/04/05/BOJ17823<h3 id="문제-링크">문제 링크</h3> <ul> <li>http://icpc.me/17823</li> </ul> <h3 id="사용-알고리즘">사용 알고리즘</h3> <ul> <li>Aliens Trick</li> <li>Parallel Binary Search</li> </ul> <h3 id="시간복잡도">시간복잡도</h3> <ul> <li>$O(N \log N \log X)$</li> </ul> <h3 id="풀이">풀이</h3> <p>구간의 양끝 원소의 사용 여부를 고정합시다. 각 구간의 양끝 원소의 사용 여부는 0부터 3까지의 정수로 인코딩할 수 있습니다. 또한, 구간의 양끝 사용 여부를 고정한 뒤 그래프를 잘 모델링하면 MCMF로 각 쿼리를 해결할 수 있습니다.</p> <p>“구간 $[l, r]$의 양끝 사용 여부가 $bit$일 때 $k$개의 부분 수열의 합의 최댓값”을 $f(l, r, bit, k)$로 정의하면, MCMF로 문제를 해결할 수 있기 때문에 $f(l,r,bit,k)-f(l,r,bit,k-1) \geq f(l,r,bit,k+1)-f(l,r,bit,k)$가 성립해서 Aliens Trick을 적용할 수 있다는 것을 알 수 있습니다.</p> <p>쿼리가 여러 개 주어지기 때문에 Parallel Binary Search를 생각해봅시다. PBS에서 우리가 수행해야 하는 연산은, “부분 수열 하나를 사용할 때 추가되는 비용이 $C$일 때 최적값”을 구하는 연산입니다.</p> <p>각 정점에서 구간 $[l, r]$의 $f(l, r, bit, 1), f(l, r, bit, 2), \cdots , f(l, r, bit, r-l+1)$을 관리하는 세그먼트 트리를 만듭시다. 만약 이러한 세그먼트 트리를 전처리했다면, PBS의 각 결정 문제는 쿼리로 주어진 구간을 나타내는 $O(\log N)$개의 정점에 저장된 함수들을 보며 해결할 수 있습니다.<br />이 세그먼트 트리는 $O(N \log N)$에 만들 수 있습니다. 두 구간 $[l, m], [m+1, r]$을 합치는 것이 병목이 될텐데, 이 부분은 두 볼록 함수의 민코프스키 합($R_{i+j} = \max(A_i + B_j)$)를 계산하는 것이기 때문에 선형 시간에 합칠 수 있습니다. 그러므로 세그먼트 트리를 전처리하는 시간 복잡도는 $T(N) = 2T(N/2) + O(N) = O(N \log N)$이 됩니다. 다만, $m$과 $m+1$을 <strong>모두 사용하는 경우</strong>에는 두 구간을 concat해주면 사용하는 부분 수열의 개수가 한 개 감소하기 때문에 배열을 왼쪽으로 한 칸 shift 해야합니다.</p> <p>이제 PBS를 합시다. 구간 개수 $k$와 추가 비용 $C$에 대해, $kC + f(k)$ 꼴의 최댓값을 계산하는 작업을 수행해야 하고, 이는 Convex Hull Trick과 매우 유사합니다. 심지어 세그먼트 트리의 각 정점에는 이미 <strong>볼록 함수</strong>가 저장되어 있기 때문에, 그냥 쿼리에 달려있는 $C$를 다 모아서 정렬한 뒤 선형 CHT 느낌으로 계산하면 됩니다.</p> <p>PBS의 각 iteration마다 $O(N \log N)$ 시간이 걸리므로 전체 시간 복잡도는 $O(N \log N \log X)$가 됩니다. 물론, 다양한 bit의 조합을 계산해야 하기 때문에 세그먼트 트리를 전처리하는 과정과 PBS의 iteration에서 상수가 8 정도 더 붙습니다.</p> <h3 id="전체-코드">전체 코드</h3> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/****************************** Author: jhnah917(Justice_Hui) g++ -std=c++17 -DLOCAL ******************************/</span> <span class="cp">#include &lt;bits/stdc++.h&gt; #define x first #define y second #define all(v) v.begin(), v.end() #define compress(v) sort(all(v)), v.erase(unique(all(v)), v.end()) #define IDX(v, x) (lower_bound(all(v), x) - v.begin()) </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">uint</span> <span class="o">=</span> <span class="kt">unsigned</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">PLL</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">SZ</span> <span class="o">=</span> <span class="mi">1</span> <span class="o">&lt;&lt;</span> <span class="mi">16</span><span class="p">;</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">INF32</span> <span class="o">=</span> <span class="mh">0x3f3f3f3f</span><span class="p">;</span> <span class="k">constexpr</span> <span class="n">ll</span> <span class="n">INF</span> <span class="o">=</span> <span class="mh">0x3f3f3f3f3f3f3f3f</span><span class="p">;</span> <span class="n">PLL</span> <span class="k">operator</span> <span class="o">+</span> <span class="p">(</span><span class="k">const</span> <span class="n">PLL</span> <span class="o">&amp;</span><span class="n">p1</span><span class="p">,</span> <span class="k">const</span> <span class="n">PLL</span> <span class="o">&amp;</span><span class="n">p2</span><span class="p">){</span> <span class="k">return</span> <span class="p">{</span><span class="n">p1</span><span class="p">.</span><span class="n">x</span> <span class="o">+</span> <span class="n">p2</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">p1</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">p2</span><span class="p">.</span><span class="n">y</span><span class="p">};</span> <span class="p">}</span> <span class="n">PLL</span> <span class="k">operator</span> <span class="o">-</span> <span class="p">(</span><span class="k">const</span> <span class="n">PLL</span> <span class="o">&amp;</span><span class="n">p1</span><span class="p">,</span> <span class="k">const</span> <span class="n">PLL</span> <span class="o">&amp;</span><span class="n">p2</span><span class="p">){</span> <span class="k">return</span> <span class="p">{</span><span class="n">p1</span><span class="p">.</span><span class="n">x</span> <span class="o">-</span> <span class="n">p2</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">p1</span><span class="p">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">p2</span><span class="p">.</span><span class="n">y</span><span class="p">};</span> <span class="p">}</span> <span class="k">struct</span> <span class="nc">Node</span><span class="p">{</span> <span class="kt">int</span> <span class="n">sz</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">V</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">];</span> <span class="n">Node</span><span class="p">()</span> <span class="o">:</span> <span class="n">Node</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="p">{}</span> <span class="n">Node</span><span class="p">(</span><span class="kt">int</span> <span class="n">sz</span><span class="p">)</span> <span class="o">:</span> <span class="n">sz</span><span class="p">(</span><span class="n">sz</span><span class="p">)</span> <span class="p">{</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span><span class="p">(</span><span class="n">sz</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="n">INF</span><span class="p">);</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">size</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">sz</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">reset</span><span class="p">(</span><span class="kt">int</span> <span class="n">_sz</span><span class="p">){</span> <span class="n">sz</span> <span class="o">=</span> <span class="n">_sz</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span><span class="p">(</span><span class="n">sz</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="n">INF</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">setValue</span><span class="p">(</span><span class="n">ll</span> <span class="n">v</span><span class="p">){</span> <span class="n">reset</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">){</span> <span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">i</span> <span class="o">||</span> <span class="n">j</span><span class="p">)</span> <span class="o">?</span> <span class="o">-</span><span class="n">INF</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span> <span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">};</span> <span class="n">Node</span> <span class="k">operator</span> <span class="o">+</span> <span class="p">(</span><span class="k">const</span> <span class="n">Node</span> <span class="o">&amp;</span><span class="n">A</span><span class="p">,</span> <span class="k">const</span> <span class="n">Node</span> <span class="o">&amp;</span><span class="n">B</span><span class="p">){</span> <span class="k">static</span> <span class="k">auto</span> <span class="n">dx</span> <span class="o">=</span> <span class="p">[](</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">vec</span><span class="p">){</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">ret</span><span class="p">;</span> <span class="n">ret</span><span class="p">.</span><span class="n">reserve</span><span class="p">(</span><span class="n">vec</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">vec</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">ret</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">vec</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">-</span> <span class="n">vec</span><span class="p">[</span><span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="p">]);</span> <span class="k">return</span> <span class="n">move</span><span class="p">(</span><span class="n">ret</span><span class="p">);</span> <span class="p">};</span> <span class="n">Node</span> <span class="n">R</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">+</span> <span class="n">B</span><span class="p">.</span><span class="n">size</span><span class="p">());</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">k</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">k</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">k</span><span class="o">++</span><span class="p">){</span> <span class="k">auto</span> <span class="n">da</span> <span class="o">=</span> <span class="n">dx</span><span class="p">(</span><span class="n">A</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]),</span> <span class="n">db</span> <span class="o">=</span> <span class="n">dx</span><span class="p">(</span><span class="n">B</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">k</span><span class="p">]);</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">res</span><span class="p">(</span><span class="n">da</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">+</span> <span class="n">db</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="n">res</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">A</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">B</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">k</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span> <span class="n">merge</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">da</span><span class="p">),</span> <span class="n">all</span><span class="p">(</span><span class="n">db</span><span class="p">),</span> <span class="n">res</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">greater</span><span class="o">&lt;&gt;</span><span class="p">());</span> <span class="n">partial_sum</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">res</span><span class="p">),</span> <span class="n">res</span><span class="p">.</span><span class="n">begin</span><span class="p">());</span> <span class="k">if</span><span class="p">(</span><span class="n">j</span><span class="p">)</span> <span class="n">res</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">res</span><span class="p">.</span><span class="n">begin</span><span class="p">());</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">s</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">s</span><span class="o">&lt;</span><span class="n">res</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">s</span><span class="o">++</span><span class="p">)</span> <span class="n">R</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">][</span><span class="n">s</span><span class="p">]</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">R</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">][</span><span class="n">s</span><span class="p">],</span> <span class="n">res</span><span class="p">[</span><span class="n">s</span><span class="p">]);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">R</span><span class="p">;</span> <span class="p">}</span> <span class="k">constexpr</span> <span class="n">PLL</span> <span class="n">BASE</span> <span class="o">=</span> <span class="n">PLL</span><span class="p">(</span><span class="o">-</span><span class="n">INF</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="k">struct</span> <span class="nc">Info</span><span class="p">{</span> <span class="n">PLL</span> <span class="n">V</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">];</span> <span class="n">Info</span><span class="p">()</span> <span class="o">:</span> <span class="n">Info</span><span class="p">(</span><span class="n">BASE</span><span class="p">,</span> <span class="n">BASE</span><span class="p">,</span> <span class="n">BASE</span><span class="p">,</span> <span class="n">BASE</span><span class="p">)</span> <span class="p">{}</span> <span class="n">Info</span><span class="p">(</span><span class="n">PLL</span> <span class="n">a</span><span class="p">,</span> <span class="n">PLL</span> <span class="n">b</span><span class="p">,</span> <span class="n">PLL</span> <span class="n">c</span><span class="p">,</span> <span class="n">PLL</span> <span class="n">d</span><span class="p">){</span> <span class="n">V</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span> <span class="n">V</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span> <span class="n">V</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">c</span><span class="p">;</span> <span class="n">V</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">d</span><span class="p">;</span> <span class="p">}</span> <span class="n">PLL</span> <span class="n">max</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">std</span><span class="o">::</span><span class="n">max</span><span class="p">({</span><span class="n">V</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">V</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">],</span> <span class="n">V</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">V</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">1</span><span class="p">]});</span> <span class="p">}</span> <span class="p">};</span> <span class="n">Info</span> <span class="nf">Merge</span><span class="p">(</span><span class="k">const</span> <span class="n">Info</span> <span class="o">&amp;</span><span class="n">A</span><span class="p">,</span> <span class="k">const</span> <span class="n">Info</span> <span class="o">&amp;</span><span class="n">B</span><span class="p">,</span> <span class="k">const</span> <span class="n">ll</span> <span class="n">lambda</span><span class="p">){</span> <span class="n">Info</span> <span class="n">R</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">k</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">k</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">k</span><span class="o">++</span><span class="p">){</span> <span class="n">PLL</span> <span class="n">now</span> <span class="o">=</span> <span class="n">A</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">+</span> <span class="n">B</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">j</span><span class="p">][</span><span class="n">k</span><span class="p">];</span> <span class="k">if</span><span class="p">(</span><span class="n">j</span><span class="p">)</span> <span class="n">now</span> <span class="o">=</span> <span class="n">now</span> <span class="o">-</span> <span class="n">PLL</span><span class="p">(</span><span class="n">lambda</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">R</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">R</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">],</span> <span class="n">now</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="n">R</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="n">Q</span><span class="p">,</span> <span class="n">A</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">ll</span> <span class="n">S</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">E</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">K</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">L</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">R</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">M</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">Info</span> <span class="n">X</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">Node</span> <span class="n">T</span><span class="p">[</span><span class="n">SZ</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">];</span> <span class="kt">int</span> <span class="n">pv</span><span class="p">[</span><span class="n">SZ</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">][</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">];</span> <span class="c1">// for CHT</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">nds</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="kt">void</span> <span class="nf">Init</span><span class="p">(</span><span class="kt">int</span> <span class="n">node</span><span class="p">,</span> <span class="kt">int</span> <span class="n">s</span><span class="p">,</span> <span class="kt">int</span> <span class="n">e</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">s</span> <span class="o">==</span> <span class="n">e</span><span class="p">){</span> <span class="n">T</span><span class="p">[</span><span class="n">node</span><span class="p">].</span><span class="n">setValue</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">s</span><span class="p">]);</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">m</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="n">e</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">;</span> <span class="n">Init</span><span class="p">(</span><span class="n">node</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">m</span><span class="p">);</span> <span class="n">Init</span><span class="p">(</span><span class="n">node</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span> <span class="o">|</span> <span class="mi">1</span><span class="p">,</span> <span class="n">m</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">e</span><span class="p">);</span> <span class="n">T</span><span class="p">[</span><span class="n">node</span><span class="p">]</span> <span class="o">=</span> <span class="n">T</span><span class="p">[</span><span class="n">node</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">T</span><span class="p">[</span><span class="n">node</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span> <span class="o">|</span> <span class="mi">1</span><span class="p">];</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Insert</span><span class="p">(</span><span class="kt">int</span> <span class="n">node</span><span class="p">,</span> <span class="kt">int</span> <span class="n">s</span><span class="p">,</span> <span class="kt">int</span> <span class="n">e</span><span class="p">,</span> <span class="kt">int</span> <span class="n">l</span><span class="p">,</span> <span class="kt">int</span> <span class="n">r</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">r</span> <span class="o">&lt;</span> <span class="n">s</span> <span class="o">||</span> <span class="n">e</span> <span class="o">&lt;</span> <span class="n">l</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">l</span> <span class="o">&lt;=</span> <span class="n">s</span> <span class="o">&amp;&amp;</span> <span class="n">e</span> <span class="o">&lt;=</span> <span class="n">r</span><span class="p">){</span> <span class="n">nds</span><span class="p">[</span><span class="n">v</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">node</span><span class="p">);</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">m</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="n">e</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">;</span> <span class="n">Insert</span><span class="p">(</span><span class="n">node</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">m</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="n">Insert</span><span class="p">(</span><span class="n">node</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span> <span class="o">|</span> <span class="mi">1</span><span class="p">,</span> <span class="n">m</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">l</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="p">}</span> <span class="n">PLL</span> <span class="nf">CHT</span><span class="p">(</span><span class="kt">int</span> <span class="n">node</span><span class="p">,</span> <span class="kt">int</span> <span class="n">i</span><span class="p">,</span> <span class="kt">int</span> <span class="n">j</span><span class="p">,</span> <span class="kt">int</span> <span class="n">q</span><span class="p">){</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">hull</span> <span class="o">=</span> <span class="n">T</span><span class="p">[</span><span class="n">node</span><span class="p">].</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">cnt</span> <span class="o">=</span> <span class="n">pv</span><span class="p">[</span><span class="n">node</span><span class="p">][</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span> <span class="k">while</span><span class="p">(</span><span class="n">cnt</span><span class="o">+</span><span class="mi">1</span> <span class="o">&lt;</span> <span class="n">hull</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">&amp;&amp;</span> <span class="n">hull</span><span class="p">[</span><span class="n">cnt</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">hull</span><span class="p">[</span><span class="n">cnt</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">M</span><span class="p">[</span><span class="n">q</span><span class="p">])</span> <span class="n">cnt</span><span class="o">++</span><span class="p">;</span> <span class="n">ll</span> <span class="n">dp</span> <span class="o">=</span> <span class="n">hull</span><span class="p">[</span><span class="n">cnt</span><span class="p">]</span> <span class="o">+</span> <span class="n">M</span><span class="p">[</span><span class="n">q</span><span class="p">]</span> <span class="o">*</span> <span class="n">cnt</span><span class="p">;</span> <span class="k">return</span> <span class="n">PLL</span><span class="p">(</span><span class="n">dp</span><span class="p">,</span> <span class="n">cnt</span><span class="p">);</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">Q</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">];</span> <span class="n">Init</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">Q</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">S</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&gt;&gt;</span> <span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&gt;&gt;</span> <span class="n">K</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">Insert</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="n">N</span><span class="p">,</span> <span class="n">S</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">i</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">Q</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="n">INF32</span><span class="p">,</span> <span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">INF32</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">O</span><span class="p">(</span><span class="n">Q</span><span class="p">);</span> <span class="n">iota</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">O</span><span class="p">),</span> <span class="mi">1</span><span class="p">);</span> <span class="k">while</span><span class="p">(</span><span class="nb">true</span><span class="p">){</span> <span class="kt">bool</span> <span class="n">fin</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">Q</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="n">fin</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mi">1</span><span class="p">)</span> <span class="n">M</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="k">else</span> <span class="n">M</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="p">}</span> <span class="n">memset</span><span class="p">(</span><span class="n">pv</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span> <span class="n">pv</span><span class="p">);</span> <span class="n">sort</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">O</span><span class="p">),</span> <span class="p">[</span><span class="o">&amp;</span><span class="p">](</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">){</span> <span class="k">return</span> <span class="n">M</span><span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">M</span><span class="p">[</span><span class="n">b</span><span class="p">];</span> <span class="p">});</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">q</span> <span class="o">:</span> <span class="n">O</span><span class="p">){</span> <span class="kt">bool</span> <span class="n">flag</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">nd</span> <span class="o">:</span> <span class="n">nds</span><span class="p">[</span><span class="n">q</span><span class="p">]){</span> <span class="n">Info</span> <span class="n">now</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">2</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">){</span> <span class="n">now</span><span class="p">.</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="n">CHT</span><span class="p">(</span><span class="n">nd</span><span class="p">,</span> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">q</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">if</span><span class="p">(</span><span class="n">flag</span><span class="p">)</span> <span class="n">X</span><span class="p">[</span><span class="n">q</span><span class="p">]</span> <span class="o">=</span> <span class="n">now</span><span class="p">;</span> <span class="k">else</span> <span class="n">X</span><span class="p">[</span><span class="n">q</span><span class="p">]</span> <span class="o">=</span> <span class="n">Merge</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="n">q</span><span class="p">],</span> <span class="n">now</span><span class="p">,</span> <span class="n">M</span><span class="p">[</span><span class="n">q</span><span class="p">]);</span> <span class="n">flag</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span><span class="p">(</span><span class="n">X</span><span class="p">[</span><span class="n">q</span><span class="p">].</span><span class="n">max</span><span class="p">().</span><span class="n">y</span> <span class="o">&gt;=</span> <span class="n">K</span><span class="p">[</span><span class="n">q</span><span class="p">])</span> <span class="n">R</span><span class="p">[</span><span class="n">q</span><span class="p">]</span> <span class="o">=</span> <span class="n">M</span><span class="p">[</span><span class="n">q</span><span class="p">];</span> <span class="k">else</span> <span class="n">L</span><span class="p">[</span><span class="n">q</span><span class="p">]</span> <span class="o">=</span> <span class="n">M</span><span class="p">[</span><span class="n">q</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> <span class="k">if</span><span class="p">(</span><span class="n">fin</span><span class="p">)</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">Q</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">X</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">max</span><span class="p">().</span><span class="n">x</span> <span class="o">-</span> <span class="n">K</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">*</span> <span class="n">L</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div>JusticeHui문제 링크 http://icpc.me/17823백준17518 Wind of Change2021-04-04T05:20:00+00:002021-04-04T05:20:00+00:00https://justicehui.github.io/ps/2021/04/04/BOJ17518<h3 id="문제-링크">문제 링크</h3> <ul> <li>http://icpc.me/17518</li> </ul> <h3 id="사용-알고리즘">사용 알고리즘</h3> <ul> <li>Centroid Decomposition</li> </ul> <h3 id="시간복잡도">시간복잡도</h3> <ul> <li>$O(N \log^2 N)$</li> </ul> <h3 id="풀이">풀이</h3> <p>루비 5 문제를 푸는 사람이라면 모두가 알고 있을 사실 2가지를 짚고 넘어가겠습니다.</p> <ul> <li>트리 $T$의 정점 $i$에서 $j$로 가는 경로의 거리 $D(i, j)$는 $T$의 Centroid Tree $C_T$에서 $i, j$의 LCA $L = LCA_{C_T}(i, j)$에 대해 $D(L, i) + D(L, j)$입니다.</li> <li>$D(i, j)$는 $T$의 Centroid Tree $C_T$에서 $i, j$의 공통 조상 $P$에 대해 $D(i, j) \leq D(P, i) + D(P, j)$를 만족합니다.</li> </ul> <p>이 두 사실을 잘 기억하고 있으면 풀이는 상당히 쉽게 나옵니다.</p> <p>$T_1, T_2$의 Centroid Tree $C_{T_1}, C_{T_2}$를 만듭시다. $C_{T_1}$에서 어떤 정점 $v$를 루트로 하는 서브 트리 내에서의 정답을 모두 구하는 방법을 알아봅시다.<br />서브 트리 내에서 $v$의 자손 $c$의 정답은, 서브 트리 내에 있는 또 다른 정점 $x$에 대해 $D_1(c, v) + D_1(v, x) + D_2(v, x)$ 이하가 됩니다. 만약 $C_{T_2}$에서 $x$의 모든 조상 $y$를 순회한다면 $D_1(c, v) + D_1(v, x) + D_2(v, y) + D_2(y, x)$를 계산해도 됩니다.<br />그러므로 $C_{T_1}$에서 $v$의 자손 $x$에 대해 $C_{T_2}$에서 $x$의 조상 $y$에 $D_1(v, x) + D_2(y, x)$의 최솟값을 저장한 뒤, 다시 $C_{T_1}$에서 $v$의 자손 $c$마다 $C_{T_2}$에서 $c$의 조상 $p$를 순회하면서 정답을 갱신하면 됩니다. (($p$에 저장된 최솟값)$+ D_1(c, v) + D_2(p, c)$ 갱신)</p> <p>$C_{T_1}$에서 $v$를 루트로 하는 서브 트리의 크기를 $S_v$라고 할 때, $v$의 서브 트리 내에서의 정답은 $O(S_v \log N)$ 시간에 구할 수 있습니다. Centroid Tree에서 $\sum S_v \in O(N \log N)$이므로 $O(N \log^2 N)$에 문제를 풀 수 있습니다.</p> <h3 id="전체-코드">전체 코드</h3> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/****************************** Author: jhnah917(Justice_Hui) g++ -std=c++17 -DLOCAL ******************************/</span> <span class="cp">#include &lt;bits/stdc++.h&gt; #define x first #define y second #define all(v) v.begin(), v.end() #define compress(v) sort(all(v)), v.erase(unique(all(v)), v.end()) #define IDX(v, x) (lower_bound(all(v), x) - v.begin()) </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">uint</span> <span class="o">=</span> <span class="kt">unsigned</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">PLL</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="n">ll</span><span class="p">,</span> <span class="n">ll</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">constexpr</span> <span class="n">ll</span> <span class="n">SZ</span> <span class="o">=</span> <span class="mi">252525</span><span class="p">,</span> <span class="n">INF</span> <span class="o">=</span> <span class="mh">0x3f3f3f3f3f3f3f3f</span><span class="p">;</span> <span class="k">struct</span> <span class="nc">MinPair</span><span class="p">{</span> <span class="n">PLL</span> <span class="n">V</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span> <span class="n">MinPair</span><span class="p">(){</span> <span class="n">V</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">V</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">PLL</span><span class="p">(</span><span class="n">INF</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">clear</span><span class="p">(){</span> <span class="n">V</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">V</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">PLL</span><span class="p">(</span><span class="n">INF</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">update</span><span class="p">(</span><span class="k">const</span> <span class="n">PLL</span> <span class="n">v</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">V</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">v</span><span class="p">)</span> <span class="n">V</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">V</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">V</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span><span class="p">;</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">V</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">v</span><span class="p">)</span> <span class="n">V</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span><span class="p">;</span> <span class="p">}</span> <span class="k">const</span> <span class="n">PLL</span><span class="o">&amp;</span> <span class="k">operator</span> <span class="p">[]</span> <span class="p">(</span><span class="kt">int</span> <span class="n">idx</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">V</span><span class="p">[</span><span class="n">idx</span><span class="p">];</span> <span class="p">}</span> <span class="p">};</span> <span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="n">S</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">U</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">PLL</span><span class="o">&gt;</span> <span class="n">G</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="n">SZ</span><span class="p">];</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">PLL</span><span class="o">&gt;</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">pInfo</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">MinPair</span> <span class="n">Small</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">ll</span> <span class="n">R</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="kt">void</span> <span class="nf">add_edge</span><span class="p">(</span><span class="kt">int</span> <span class="n">id</span><span class="p">,</span> <span class="kt">int</span> <span class="n">s</span><span class="p">,</span> <span class="kt">int</span> <span class="n">e</span><span class="p">,</span> <span class="kt">int</span> <span class="n">x</span><span class="p">){</span> <span class="n">G</span><span class="p">[</span><span class="n">id</span><span class="p">][</span><span class="n">s</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span> <span class="n">G</span><span class="p">[</span><span class="n">id</span><span class="p">][</span><span class="n">e</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">get_sz</span><span class="p">(</span><span class="kt">int</span> <span class="n">id</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">){</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">id</span><span class="p">][</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">U</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span> <span class="o">!=</span> <span class="n">b</span><span class="p">)</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">+=</span> <span class="n">get_sz</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="k">return</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">];</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">get_cent</span><span class="p">(</span><span class="kt">int</span> <span class="n">id</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">tot</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">id</span><span class="p">][</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">U</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span> <span class="o">!=</span> <span class="n">b</span> <span class="o">&amp;&amp;</span> <span class="n">S</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">*</span><span class="mi">2</span> <span class="o">&gt;</span> <span class="n">tot</span><span class="p">)</span> <span class="k">return</span> <span class="n">get_cent</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">tot</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="k">return</span> <span class="n">v</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">gather</span><span class="p">(</span><span class="kt">int</span> <span class="n">id</span><span class="p">,</span> <span class="kt">int</span> <span class="n">rt</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">,</span> <span class="kt">int</span> <span class="n">d</span><span class="p">,</span> <span class="n">ll</span> <span class="n">c</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">id</span><span class="p">)</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">rt</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">c</span><span class="p">);</span> <span class="k">else</span> <span class="n">pInfo</span><span class="p">[</span><span class="n">v</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">rt</span><span class="p">,</span> <span class="n">c</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">id</span><span class="p">][</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">U</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span> <span class="o">!=</span> <span class="n">b</span><span class="p">)</span> <span class="n">gather</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">rt</span><span class="p">,</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">d</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="o">+</span><span class="n">i</span><span class="p">.</span><span class="n">y</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">cd</span><span class="p">(</span><span class="kt">int</span> <span class="n">id</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="kt">int</span> <span class="n">cent</span> <span class="o">=</span> <span class="n">get_cent</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">get_sz</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">),</span> <span class="o">-</span><span class="mi">1</span><span class="p">);</span> <span class="n">gather</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">cent</span><span class="p">,</span> <span class="n">cent</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">U</span><span class="p">[</span><span class="n">cent</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">id</span><span class="p">][</span><span class="n">cent</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">U</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">])</span> <span class="n">cd</span><span class="p">(</span><span class="n">id</span><span class="p">,</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">);</span> <span class="n">U</span><span class="p">[</span><span class="n">cent</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Go</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">j</span> <span class="o">:</span> <span class="n">pInfo</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">])</span> <span class="n">Small</span><span class="p">[</span><span class="n">j</span><span class="p">.</span><span class="n">x</span><span class="p">].</span><span class="n">clear</span><span class="p">();</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">j</span> <span class="o">:</span> <span class="n">pInfo</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">])</span> <span class="n">Small</span><span class="p">[</span><span class="n">j</span><span class="p">.</span><span class="n">x</span><span class="p">].</span><span class="n">update</span><span class="p">({</span><span class="n">i</span><span class="p">.</span><span class="n">y</span><span class="o">+</span><span class="n">j</span><span class="p">.</span><span class="n">y</span><span class="p">,</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">});</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">j</span> <span class="o">:</span> <span class="n">pInfo</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">])</span> <span class="p">{</span> <span class="k">if</span><span class="p">(</span><span class="n">Small</span><span class="p">[</span><span class="n">j</span><span class="p">.</span><span class="n">x</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">y</span> <span class="o">!=</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">)</span> <span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">],</span> <span class="n">i</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">j</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">Small</span><span class="p">[</span><span class="n">j</span><span class="p">.</span><span class="n">x</span><span class="p">][</span><span class="mi">0</span><span class="p">].</span><span class="n">x</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">Small</span><span class="p">[</span><span class="n">j</span><span class="p">.</span><span class="n">x</span><span class="p">][</span><span class="mi">1</span><span class="p">].</span><span class="n">y</span> <span class="o">!=</span> <span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">)</span> <span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">min</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">],</span> <span class="n">i</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">j</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">Small</span><span class="p">[</span><span class="n">j</span><span class="p">.</span><span class="n">x</span><span class="p">][</span><span class="mi">1</span><span class="p">].</span><span class="n">x</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span><span class="n">s</span><span class="p">,</span><span class="n">e</span><span class="p">,</span><span class="n">x</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">s</span> <span class="o">&gt;&gt;</span> <span class="n">e</span> <span class="o">&gt;&gt;</span> <span class="n">x</span><span class="p">,</span> <span class="n">add_edge</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span><span class="n">s</span><span class="p">,</span><span class="n">e</span><span class="p">,</span><span class="n">x</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">s</span> <span class="o">&gt;&gt;</span> <span class="n">e</span> <span class="o">&gt;&gt;</span> <span class="n">x</span><span class="p">,</span> <span class="n">add_edge</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">s</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">x</span><span class="p">);</span> <span class="n">cd</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">cd</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">memset</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="mh">0x3f</span><span class="p">,</span> <span class="k">sizeof</span> <span class="n">R</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">Go</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div>JusticeHui문제 링크 http://icpc.me/17518백준19028 Link Cut Digraph2021-04-03T02:55:00+00:002021-04-03T02:55:00+00:00https://justicehui.github.io/ps/2021/04/03/BOJ19028<h3 id="문제-링크">문제 링크</h3> <ul> <li>http://icpc.me/19028</li> </ul> <h3 id="사용-알고리즘">사용 알고리즘</h3> <ul> <li>Offline Incremental SCC</li> </ul> <h3 id="시간복잡도">시간복잡도</h3> <ul> <li>$O(M \log M)$</li> </ul> <h3 id="풀이">풀이</h3> <p><a href="/poi/2019/12/27/BOJ8496/">BOJ 8496 Godzilla(2009 POI ONTAK) 문제 풀이</a>에서 설명한 Offline Incremental SCC를 구현하는 문제입니다.</p> <p>해당 알고리즘에서 UnionFind가 관리하는 정보를 잘 이해하고 있다면 쉽게 문제를 풀 수 있습니다.</p> <h3 id="전체-코드">전체 코드</h3> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/****************************** Author: jhnah917(Justice_Hui) g++ -std=c++17 -DLOCAL ******************************/</span> <span class="cp">#include &lt;bits/stdc++.h&gt; #define x first #define y second #define all(v) v.begin(), v.end() #define compress(v) sort(all(v)), v.erase(unique(all(v)), v.end()) #define IDX(v, x) (lower_bound(all(v), x) - v.begin()) </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">uint</span> <span class="o">=</span> <span class="kt">unsigned</span><span class="p">;</span> <span class="k">using</span> <span class="n">ll</span> <span class="o">=</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">ull</span> <span class="o">=</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span><span class="p">;</span> <span class="k">using</span> <span class="n">PII</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">template</span><span class="o">&lt;</span><span class="kt">size_t</span> <span class="n">_Sz</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">UnionFind</span> <span class="p">{</span> <span class="kt">int</span> <span class="n">P</span><span class="p">[</span><span class="n">_Sz</span><span class="p">],</span> <span class="n">S</span><span class="p">[</span><span class="n">_Sz</span><span class="p">];</span> <span class="n">ll</span> <span class="n">CS</span><span class="p">;</span> <span class="n">UnionFind</span><span class="p">(){</span> <span class="n">iota</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="n">P</span><span class="o">+</span><span class="n">_Sz</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> <span class="n">fill</span><span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="n">S</span><span class="o">+</span><span class="n">_Sz</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="n">CS</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">find</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="k">return</span> <span class="n">v</span> <span class="o">==</span> <span class="n">P</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">?</span> <span class="n">v</span> <span class="o">:</span> <span class="n">P</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">P</span><span class="p">[</span><span class="n">v</span><span class="p">]);</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">merge</span><span class="p">(</span><span class="kt">int</span> <span class="n">u</span><span class="p">,</span> <span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="n">u</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">u</span><span class="p">);</span> <span class="n">v</span> <span class="o">=</span> <span class="n">find</span><span class="p">(</span><span class="n">v</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">u</span> <span class="o">==</span> <span class="n">v</span><span class="p">)</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="n">CS</span> <span class="o">-=</span> <span class="mi">1LL</span> <span class="o">*</span> <span class="n">S</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="n">CS</span> <span class="o">-=</span> <span class="mi">1LL</span> <span class="o">*</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">+=</span> <span class="n">S</span><span class="p">[</span><span class="n">u</span><span class="p">];</span> <span class="n">CS</span> <span class="o">+=</span> <span class="mi">1LL</span> <span class="o">*</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span><span class="p">;</span> <span class="n">P</span><span class="p">[</span><span class="n">u</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span><span class="p">;</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="k">template</span><span class="o">&lt;</span><span class="kt">size_t</span> <span class="n">_Sz</span><span class="p">&gt;</span> <span class="k">struct</span> <span class="nc">SCC</span> <span class="p">{</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">G</span><span class="p">[</span><span class="n">_Sz</span><span class="p">],</span> <span class="n">R</span><span class="p">[</span><span class="n">_Sz</span><span class="p">],</span> <span class="n">dfn</span><span class="p">,</span> <span class="n">use</span><span class="p">;</span> <span class="kt">int</span> <span class="n">id</span><span class="p">[</span><span class="n">_Sz</span><span class="p">],</span> <span class="n">pv</span><span class="p">;</span> <span class="kt">int</span> <span class="n">cnt</span><span class="p">[</span><span class="n">_Sz</span><span class="p">];</span> <span class="kt">void</span> <span class="n">clear</span><span class="p">(){</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">use</span><span class="p">)</span> <span class="n">cnt</span><span class="p">[</span><span class="n">id</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">G</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">clear</span><span class="p">(),</span> <span class="n">R</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">clear</span><span class="p">(),</span> <span class="n">id</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">dfn</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span> <span class="n">use</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span> <span class="n">pv</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">addEdge</span><span class="p">(</span><span class="kt">int</span> <span class="n">s</span><span class="p">,</span> <span class="kt">int</span> <span class="n">e</span><span class="p">){</span> <span class="n">G</span><span class="p">[</span><span class="n">s</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">e</span><span class="p">);</span> <span class="n">R</span><span class="p">[</span><span class="n">e</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">s</span><span class="p">);</span> <span class="n">use</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">s</span><span class="p">);</span> <span class="n">use</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">e</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">dfs</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="n">id</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">id</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="n">dfs</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="n">dfn</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">v</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">rfs</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">color</span><span class="p">){</span> <span class="n">id</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">color</span><span class="p">;</span> <span class="n">cnt</span><span class="p">[</span><span class="n">color</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">R</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">id</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="n">rfs</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">color</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="n">getSCC</span><span class="p">(){</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">use</span><span class="p">)</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">id</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="n">dfs</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="n">reverse</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">dfn</span><span class="p">));</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">use</span><span class="p">)</span> <span class="n">id</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">dfn</span><span class="p">)</span> <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">id</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="n">rfs</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="o">++</span><span class="n">pv</span><span class="p">);</span> <span class="p">}</span> <span class="p">};</span> <span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="n">M</span><span class="p">;</span> <span class="n">PII</span> <span class="n">E</span><span class="p">[</span><span class="mi">252525</span><span class="p">];</span> <span class="n">UnionFind</span><span class="o">&lt;</span><span class="mi">101010</span><span class="o">&gt;</span> <span class="n">uf</span><span class="p">;</span> <span class="n">SCC</span><span class="o">&lt;</span><span class="mi">101010</span><span class="o">&gt;</span> <span class="n">scc</span><span class="p">;</span> <span class="kt">int</span> <span class="n">Time</span><span class="p">[</span><span class="mi">252525</span><span class="p">];</span> <span class="n">ll</span> <span class="n">Res</span><span class="p">[</span><span class="mi">252525</span><span class="p">];</span> <span class="kt">void</span> <span class="nf">Solve</span><span class="p">(</span><span class="kt">int</span> <span class="n">s</span><span class="p">,</span> <span class="kt">int</span> <span class="n">e</span><span class="p">,</span> <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">li</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">s</span> <span class="o">==</span> <span class="n">e</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">i</span> <span class="o">:</span> <span class="n">li</span><span class="p">)</span> <span class="n">uf</span><span class="p">.</span><span class="n">merge</span><span class="p">(</span><span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">x</span><span class="p">,</span> <span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">y</span><span class="p">),</span> <span class="n">Time</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">s</span><span class="p">;</span> <span class="n">Res</span><span class="p">[</span><span class="n">s</span><span class="p">]</span> <span class="o">=</span> <span class="n">uf</span><span class="p">.</span><span class="n">CS</span><span class="p">;</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="n">scc</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span> <span class="kt">int</span> <span class="n">m</span> <span class="o">=</span> <span class="n">s</span> <span class="o">+</span> <span class="n">e</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">i</span> <span class="o">:</span> <span class="n">li</span><span class="p">){</span> <span class="kt">int</span> <span class="n">st</span> <span class="o">=</span> <span class="n">uf</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">x</span><span class="p">),</span> <span class="n">ed</span> <span class="o">=</span> <span class="n">uf</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">y</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">i</span> <span class="o">&lt;=</span> <span class="n">m</span><span class="p">)</span> <span class="n">scc</span><span class="p">.</span><span class="n">addEdge</span><span class="p">(</span><span class="n">st</span><span class="p">,</span> <span class="n">ed</span><span class="p">);</span> <span class="p">}</span> <span class="n">scc</span><span class="p">.</span><span class="n">getSCC</span><span class="p">();</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">l</span><span class="p">,</span> <span class="n">r</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">i</span> <span class="o">:</span> <span class="n">li</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">i</span> <span class="o">&gt;</span> <span class="n">m</span><span class="p">){</span> <span class="n">r</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="k">continue</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">st</span> <span class="o">=</span> <span class="n">uf</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">x</span><span class="p">),</span> <span class="n">ed</span> <span class="o">=</span> <span class="n">uf</span><span class="p">.</span><span class="n">find</span><span class="p">(</span><span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">y</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">scc</span><span class="p">.</span><span class="n">id</span><span class="p">[</span><span class="n">st</span><span class="p">]</span> <span class="o">==</span> <span class="n">scc</span><span class="p">.</span><span class="n">id</span><span class="p">[</span><span class="n">ed</span><span class="p">])</span> <span class="n">l</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="k">else</span> <span class="n">r</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="p">}</span> <span class="n">Solve</span><span class="p">(</span><span class="n">s</span><span class="p">,</span> <span class="n">m</span><span class="p">,</span> <span class="n">l</span><span class="p">);</span> <span class="n">Solve</span><span class="p">(</span><span class="n">m</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">e</span><span class="p">,</span> <span class="n">r</span><span class="p">);</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">M</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">M</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">x</span> <span class="o">&gt;&gt;</span> <span class="n">E</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">y</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">li</span><span class="p">;</span> <span class="n">li</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">M</span><span class="p">);</span> <span class="n">iota</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">li</span><span class="p">),</span> <span class="mi">1</span><span class="p">);</span> <span class="n">Solve</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">M</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">li</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">M</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">Res</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div>JusticeHui문제 링크 http://icpc.me/19028백준18932 트리와 쿼리 162021-04-02T02:33:00+00:002021-04-02T02:33:00+00:00https://justicehui.github.io/ps/2021/04/02/BOJ18932<h3 id="문제-링크">문제 링크</h3> <ul> <li>http://icpc.me/18932</li> </ul> <h3 id="사용-알고리즘">사용 알고리즘</h3> <ul> <li>Centroid Decomposition</li> </ul> <h3 id="시간복잡도">시간복잡도</h3> <ul> <li>$O((N+Q) \log^2 N)$</li> </ul> <h3 id="풀이">풀이</h3> <p>1번 쿼리(간선 추가 쿼리)가 모두 주어진 다음 2번 쿼리가 주어지는, 조금 더 쉬운 문제를 생각해봅시다.<br /> 이 문제는 단순히 Centroid Tree의 각 정점에서 도달할 수 있는 다른 정점까지 도달하는 거리를 저장하는 것으로 $O(Q \log^2 N)$ 해결할 수 있습니다.</p> <p>간선 추가 쿼리는 Centroid Decomposition 정보(Centroid Tree)를 Small to Large로 합치면 될 것 같다는 생각을 할 수 있습니다. 구체적으로, 연결해야 하는 두 정점이 속한 Centroid Tree의 루트부터 시작해서, 큰 서브 트리 밑에 작은 서브 트리를 넣어주면 됩니다.<br /> 하지만 잘 생각해보면 이 방식을 이용해 Centroid Tree를 합쳐도 최악의 경우에는 선형 시간을 피할 수 없다는 것을 알 수 있습니다.</p> <p>Centroid Tree가 너무 균형이 안 맞는 경우에는 어쩔 수 없이 Centroid Tree를 다시 구축(rebuild)해야 합니다.</p> <p>Centroid Tree에서 각 정점을 루트로 하는 서브 트리마다, 그 정점을 루트로 하는 서브 트리가 마지막으로 rebuild 되었을 때의 크기 $L_v$를 저장합시다. 간선 추가 쿼리에 의해 서브 트리가 합쳐질 때, 합친 크기가 $L_v$의 2배 이상이 될 때마다 rebuild하면, 각 서브 트리의 크기는 항상 부모 서브 트리의 $3/4$ 이하가 됩니다. 그러므로 Centroid Tree의 높이를 $O(\log N)$으로 유지할 수 있습니다.</p> <p>아래 코드는 구현의 편의를 위해서 서브 트리를 합칠 때 부모 서브 트리의 $3/4$ 초과일 때 rebuild하는 방식으로 구현했습니다.</p> <h3 id="전체-코드">전체 코드</h3> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/****************************** Author: jhnah917(Justice_Hui) g++ -std=c++17 -DLOCAL ******************************/</span> <span class="cp">#include &lt;bits/stdc++.h&gt; #define x first #define y second </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">using</span> <span class="n">PII</span> <span class="o">=</span> <span class="n">pair</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span><span class="p">;</span> <span class="k">constexpr</span> <span class="kt">int</span> <span class="n">SZ</span> <span class="o">=</span> <span class="mi">101010</span><span class="p">,</span> <span class="n">INF</span> <span class="o">=</span> <span class="mh">0x3f3f3f3f</span><span class="p">;</span> <span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="n">Q</span><span class="p">,</span> <span class="n">lst</span><span class="p">;</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">G</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="kt">int</span> <span class="n">S</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="kt">int</span> <span class="n">CP</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">CS</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">C_LV</span><span class="p">[</span><span class="n">SZ</span><span class="p">],</span> <span class="n">C_ID</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="c1">// c_tree parent, size, level, child id, child cnt</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">Info</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="n">map</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;</span> <span class="n">D</span><span class="p">[</span><span class="n">SZ</span><span class="p">];</span> <span class="kt">void</span> <span class="nf">add</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">vec</span><span class="p">,</span> <span class="kt">int</span> <span class="n">idx</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">idx</span> <span class="o">&gt;=</span> <span class="n">vec</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="n">vec</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">idx</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="n">vec</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">get</span><span class="p">(</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">vec</span><span class="p">,</span> <span class="kt">int</span> <span class="n">idx</span><span class="p">){</span> <span class="k">return</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">idx</span> <span class="o">&amp;&amp;</span> <span class="n">idx</span> <span class="o">&lt;</span> <span class="n">vec</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">?</span> <span class="n">vec</span><span class="p">[</span><span class="n">idx</span><span class="p">]</span> <span class="o">:</span> <span class="mi">0</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">get_sz</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">=-</span><span class="mi">1</span><span class="p">){</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="n">i</span> <span class="o">!=</span> <span class="n">b</span> <span class="o">&amp;&amp;</span> <span class="n">C_LV</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="n">INF</span><span class="p">)</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">+=</span> <span class="n">get_sz</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="k">return</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">];</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">get_cent</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">tot</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="o">=-</span><span class="mi">1</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="n">i</span> <span class="o">!=</span> <span class="n">b</span> <span class="o">&amp;&amp;</span> <span class="n">C_LV</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="n">INF</span> <span class="o">&amp;&amp;</span> <span class="n">S</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">*</span><span class="mi">2</span> <span class="o">&gt;</span> <span class="n">tot</span><span class="p">)</span> <span class="k">return</span> <span class="n">get_cent</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">tot</span><span class="p">,</span> <span class="n">v</span><span class="p">);</span> <span class="k">return</span> <span class="n">v</span><span class="p">;</span> <span class="p">}</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">PII</span><span class="o">&gt;</span> <span class="n">gather</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">,</span> <span class="kt">int</span> <span class="n">lim</span><span class="p">,</span> <span class="kt">int</span> <span class="n">d</span><span class="p">){</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">PII</span><span class="o">&gt;</span> <span class="n">ret</span><span class="p">;</span> <span class="n">function</span><span class="o">&lt;</span><span class="kt">void</span><span class="p">(</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="p">,</span><span class="kt">int</span><span class="p">)</span><span class="o">&gt;</span> <span class="n">dfs</span> <span class="o">=</span> <span class="p">[</span><span class="o">&amp;</span><span class="n">ret</span><span class="p">,</span><span class="o">&amp;</span><span class="n">lim</span><span class="p">,</span><span class="o">&amp;</span><span class="n">dfs</span><span class="p">](</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">,</span> <span class="kt">int</span> <span class="n">d</span><span class="p">){</span> <span class="n">ret</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">d</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">v</span><span class="p">])</span> <span class="k">if</span><span class="p">(</span><span class="n">i</span> <span class="o">!=</span> <span class="n">b</span> <span class="o">&amp;&amp;</span> <span class="n">C_LV</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="n">lim</span><span class="p">)</span> <span class="n">dfs</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">v</span><span class="p">,</span> <span class="n">d</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="p">};</span> <span class="n">dfs</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">d</span><span class="p">);</span> <span class="k">return</span> <span class="n">move</span><span class="p">(</span><span class="n">ret</span><span class="p">);</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">CD</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">lv</span><span class="p">){</span> <span class="kt">int</span> <span class="n">cent</span> <span class="o">=</span> <span class="n">get_cent</span><span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">get_sz</span><span class="p">(</span><span class="n">v</span><span class="p">));</span> <span class="n">CS</span><span class="p">[</span><span class="n">cent</span><span class="p">]</span> <span class="o">=</span> <span class="n">S</span><span class="p">[</span><span class="n">v</span><span class="p">];</span> <span class="n">C_LV</span><span class="p">[</span><span class="n">cent</span><span class="p">]</span> <span class="o">=</span> <span class="n">lv</span><span class="p">;</span> <span class="n">Info</span><span class="p">[</span><span class="n">cent</span><span class="p">].</span><span class="n">clear</span><span class="p">();</span> <span class="n">Info</span><span class="p">[</span><span class="n">cent</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">cent</span><span class="p">].</span><span class="n">clear</span><span class="p">();</span> <span class="n">D</span><span class="p">[</span><span class="n">cent</span><span class="p">].</span><span class="n">clear</span><span class="p">();</span> <span class="kt">int</span> <span class="n">idx</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">cent</span><span class="p">]){</span> <span class="k">if</span><span class="p">(</span><span class="n">C_LV</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">!=</span> <span class="n">INF</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span> <span class="n">idx</span><span class="o">++</span><span class="p">;</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">cent</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">();</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">j</span> <span class="o">:</span> <span class="n">gather</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">cent</span><span class="p">,</span> <span class="n">INF</span><span class="p">,</span> <span class="mi">1</span><span class="p">)){</span> <span class="n">add</span><span class="p">(</span><span class="n">Info</span><span class="p">[</span><span class="n">cent</span><span class="p">],</span> <span class="n">j</span><span class="p">.</span><span class="n">y</span><span class="p">);</span> <span class="n">add</span><span class="p">(</span><span class="n">cInfo</span><span class="p">[</span><span class="n">cent</span><span class="p">][</span><span class="n">idx</span><span class="p">],</span> <span class="n">j</span><span class="p">.</span><span class="n">y</span><span class="p">);</span> <span class="n">D</span><span class="p">[</span><span class="n">cent</span><span class="p">][</span><span class="n">j</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">j</span><span class="p">.</span><span class="n">y</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">nxt</span> <span class="o">=</span> <span class="n">CD</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">lv</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="n">CP</span><span class="p">[</span><span class="n">nxt</span><span class="p">]</span> <span class="o">=</span> <span class="n">cent</span><span class="p">;</span> <span class="n">C_ID</span><span class="p">[</span><span class="n">nxt</span><span class="p">]</span> <span class="o">=</span> <span class="n">idx</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="n">cent</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Query1</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">){</span> <span class="n">G</span><span class="p">[</span><span class="n">a</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">b</span><span class="p">);</span> <span class="n">G</span><span class="p">[</span><span class="n">b</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">a</span><span class="p">);</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">a_path</span><span class="p">,</span> <span class="n">b_path</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">a</span><span class="p">;</span> <span class="n">i</span><span class="o">!=-</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">=</span><span class="n">CP</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="n">a_path</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">b</span><span class="p">;</span> <span class="n">i</span><span class="o">!=-</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">=</span><span class="n">CP</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="n">b_path</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="kt">int</span> <span class="n">prv</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">pIdx</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="k">while</span><span class="p">(</span><span class="n">a_path</span><span class="p">.</span><span class="n">size</span><span class="p">()){</span> <span class="kt">int</span> <span class="n">a_root</span> <span class="o">=</span> <span class="n">a_path</span><span class="p">.</span><span class="n">back</span><span class="p">(),</span> <span class="n">b_root</span> <span class="o">=</span> <span class="n">b_path</span><span class="p">.</span><span class="n">back</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="n">CS</span><span class="p">[</span><span class="n">a_root</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">CS</span><span class="p">[</span><span class="n">b_root</span><span class="p">])</span> <span class="n">swap</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">),</span> <span class="n">swap</span><span class="p">(</span><span class="n">a_path</span><span class="p">,</span> <span class="n">b_path</span><span class="p">),</span> <span class="n">swap</span><span class="p">(</span><span class="n">a_root</span><span class="p">,</span> <span class="n">b_root</span><span class="p">);</span> <span class="n">a_path</span><span class="p">.</span><span class="n">pop_back</span><span class="p">();</span> <span class="k">if</span><span class="p">(</span><span class="n">CS</span><span class="p">[</span><span class="n">b_root</span><span class="p">]</span> <span class="o">*</span> <span class="mi">4</span> <span class="o">&gt;</span> <span class="n">CS</span><span class="p">[</span><span class="n">a_root</span><span class="p">]</span> <span class="o">*</span> <span class="mi">3</span><span class="p">){</span> <span class="kt">int</span> <span class="n">lv</span> <span class="o">=</span> <span class="n">C_LV</span><span class="p">[</span><span class="n">a_root</span><span class="p">];</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">j</span> <span class="o">:</span> <span class="n">gather</span><span class="p">(</span><span class="n">a_root</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">lv</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span> <span class="n">C_LV</span><span class="p">[</span><span class="n">j</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">INF</span><span class="p">;</span> <span class="kt">int</span> <span class="n">new_cent</span> <span class="o">=</span> <span class="n">CD</span><span class="p">(</span><span class="n">a_root</span><span class="p">,</span> <span class="n">lv</span><span class="p">);</span> <span class="n">CP</span><span class="p">[</span><span class="n">new_cent</span><span class="p">]</span> <span class="o">=</span> <span class="n">prv</span><span class="p">;</span> <span class="n">C_ID</span><span class="p">[</span><span class="n">new_cent</span><span class="p">]</span> <span class="o">=</span> <span class="n">pIdx</span><span class="p">;</span> <span class="k">return</span><span class="p">;</span> <span class="p">}</span> <span class="n">CP</span><span class="p">[</span><span class="n">a_root</span><span class="p">]</span> <span class="o">=</span> <span class="n">prv</span><span class="p">;</span> <span class="n">CS</span><span class="p">[</span><span class="n">a_root</span><span class="p">]</span> <span class="o">+=</span> <span class="n">CS</span><span class="p">[</span><span class="n">b_root</span><span class="p">];</span> <span class="n">C_ID</span><span class="p">[</span><span class="n">a_root</span><span class="p">]</span> <span class="o">=</span> <span class="n">pIdx</span><span class="p">;</span> <span class="kt">int</span> <span class="n">idx</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">a_path</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="n">idx</span> <span class="o">=</span> <span class="n">C_ID</span><span class="p">[</span><span class="n">a_path</span><span class="p">.</span><span class="n">back</span><span class="p">()];</span> <span class="k">else</span> <span class="n">idx</span> <span class="o">=</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">a_root</span><span class="p">].</span><span class="n">size</span><span class="p">(),</span> <span class="n">cInfo</span><span class="p">[</span><span class="n">a_root</span><span class="p">].</span><span class="n">emplace_back</span><span class="p">();</span> <span class="kt">int</span> <span class="n">d</span> <span class="o">=</span> <span class="n">D</span><span class="p">[</span><span class="n">a_root</span><span class="p">][</span><span class="n">a</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="n">i</span> <span class="o">:</span> <span class="n">gather</span><span class="p">(</span><span class="n">b</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">C_LV</span><span class="p">[</span><span class="n">b_root</span><span class="p">],</span> <span class="mi">0</span><span class="p">)){</span> <span class="n">C_LV</span><span class="p">[</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span><span class="o">++</span><span class="p">;</span> <span class="n">add</span><span class="p">(</span><span class="n">Info</span><span class="p">[</span><span class="n">a_root</span><span class="p">],</span> <span class="n">i</span><span class="p">.</span><span class="n">y</span><span class="o">+</span><span class="n">d</span><span class="p">);</span> <span class="n">add</span><span class="p">(</span><span class="n">cInfo</span><span class="p">[</span><span class="n">a_root</span><span class="p">][</span><span class="n">idx</span><span class="p">],</span> <span class="n">i</span><span class="p">.</span><span class="n">y</span><span class="o">+</span><span class="n">d</span><span class="p">);</span> <span class="n">D</span><span class="p">[</span><span class="n">a_root</span><span class="p">][</span><span class="n">i</span><span class="p">.</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span><span class="p">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">d</span><span class="p">;</span> <span class="p">}</span> <span class="n">prv</span> <span class="o">=</span> <span class="n">a_root</span><span class="p">;</span> <span class="n">pIdx</span> <span class="o">=</span> <span class="n">idx</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">bv</span> <span class="o">=</span> <span class="n">b_path</span><span class="p">.</span><span class="n">back</span><span class="p">();</span> <span class="n">CP</span><span class="p">[</span><span class="n">bv</span><span class="p">]</span> <span class="o">=</span> <span class="n">prv</span><span class="p">;</span> <span class="n">C_ID</span><span class="p">[</span><span class="n">bv</span><span class="p">]</span> <span class="o">=</span> <span class="n">pIdx</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Query2</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">,</span> <span class="kt">int</span> <span class="n">k</span><span class="p">){</span> <span class="kt">int</span> <span class="n">ans</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="n">v</span><span class="p">,</span> <span class="n">prv</span><span class="o">=-</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">!=-</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">=</span><span class="n">CP</span><span class="p">[</span><span class="n">i</span><span class="p">]){</span> <span class="kt">int</span> <span class="n">d</span> <span class="o">=</span> <span class="n">k</span> <span class="o">-</span> <span class="n">D</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">v</span><span class="p">];</span> <span class="n">ans</span> <span class="o">+=</span> <span class="n">get</span><span class="p">(</span><span class="n">Info</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">d</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">prv</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="n">ans</span> <span class="o">-=</span> <span class="n">get</span><span class="p">(</span><span class="n">cInfo</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">C_ID</span><span class="p">[</span><span class="n">prv</span><span class="p">]],</span> <span class="n">d</span><span class="p">);</span> <span class="n">prv</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">ans</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="n">lst</span> <span class="o">=</span> <span class="n">ans</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span> <span class="o">&gt;&gt;</span> <span class="n">Q</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="n">CP</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">CS</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="n">C_ID</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">Info</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span> <span class="p">}</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">Q</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="kt">int</span> <span class="n">op</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">op</span> <span class="o">&gt;&gt;</span> <span class="n">a</span> <span class="o">&gt;&gt;</span> <span class="n">b</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">op</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="n">Query1</span><span class="p">((</span><span class="n">a</span> <span class="o">+</span> <span class="n">lst</span><span class="p">)</span> <span class="o">%</span> <span class="n">N</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span> <span class="o">+</span> <span class="n">lst</span><span class="p">)</span> <span class="o">%</span> <span class="n">N</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span> <span class="k">else</span> <span class="n">Query2</span><span class="p">((</span><span class="n">a</span> <span class="o">+</span> <span class="n">lst</span><span class="p">)</span> <span class="o">%</span> <span class="n">N</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="p">(</span><span class="n">b</span> <span class="o">+</span> <span class="n">lst</span><span class="p">)</span> <span class="o">%</span> <span class="n">N</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div>JusticeHui문제 링크 http://icpc.me/18932백준14832 Dice Straight (Large)2021-04-01T02:46:00+00:002021-04-01T02:46:00+00:00https://justicehui.github.io/ps/2021/04/01/BOJ14832<h3 id="문제-링크">문제 링크</h3> <ul> <li>http://icpc.me/14832</li> </ul> <h3 id="문제-출처">문제 출처</h3> <ul> <li>Google Code Jam 2017 World Finals A2</li> </ul> <h3 id="사용-알고리즘">사용 알고리즘</h3> <ul> <li>이분 매칭</li> <li>투포인터</li> </ul> <h3 id="시간복잡도">시간복잡도</h3> <ul> <li>$O(N^2)$ per testcase</li> </ul> <h3 id="풀이">풀이</h3> <p>$O(N^4), O(N^3), O(N^2)$ 풀이를 차례대로 알아봅시다. 실제 대회에서는 $O(N^3)$ 풀이를 구현하면 10점, $O(N^2)$ 풀이를 구현하면 25점을 받을 수 있었습니다.</p> <h4 id="on4">$O(N^4)$</h4> <p>각 주사위는 최대 한 개의 수를 표현하게 됩니다. 주사위가 하나의 수를 선택한다는 점에서 이분 매칭을 생각해볼 수 있습니다.<br /> 주사위의 집합 $L$, 한 번 이상 등장하는 수의 집합 $R$, 주사위와 그 주사위에 써있는 수를 연결한 간선 집합 $E$가 있을 때, 적당한 집합 $r \subset R$에 대해 이분 그래프 $G_r = (L, r, E)$의 최대 매칭을 구하는 문제로 환원할 수 있습니다.</p> <p>적당한 집합 $r \subset R$의 원소를 모두 정렬하면 <strong>연속한 자연수</strong>가 되어야 하고, 정렬된 배열의 <strong>구간</strong>을 선택한다고 생각하면 $O(N^2)$ 가지의 구간을 생각할 수 있습니다.<br /> $O(\vert L \cup r \vert \cdot \vert E \vert) = O(N^2)$ 이분 매칭을 $O(N^2)$번 수행하면 $O(N^4)$에 문제를 풀 수 있습니다.</p> <h4 id="on3">$O(N^3)$</h4> <p>투포인터를 이용하면 $O(N)$개의 구간만 봐도 충분합니다.<br /> 현재 구간을 나타내는 $r$이 있을 때, 세 가지 케이스로 분류할 수 있습니다.</p> <ol> <li>$e \in R, e = \max(r) + 1$인 원소 $e$가 존재하지 않음</li> <li>$e$를 $r$에 추가했을 때 매칭의 개수가 증가</li> <li>증가하지 않음</li> </ol> <p>2번의 경우 구간의 끝점을 뒤로 1만큼 밀고, 3번의 경우에는 구간의 시작점을 1만큼 뒤로 당기면 됩니다.<br /> 마지막으로 1번의 경우에는 끝점을 뒤로 1만큼 밀고, 시작점을 끝점과 동일하게 만들어주면 됩니다.</p> <p>총 $O(N)$개의 구간에 대해 $O(N^2)$ 이분 매칭을 수행하면 $O(N^3)$에 문제를 풀 수 있고, Dice Straight (Small) 문제에서 AC를 받을 수 있습니다.</p> <h4 id="on2">$O(N^2)$</h4> <p>이제 구간의 개수를 더 줄이는 것은 불가능합니다. 이분 매칭을 어떻게 최적화할 수 있을까요?</p> <p>투포인터에서 포인터의 이동 과정을 생각해봅시다.<br /> 끝점이 이동하면 최대 1만큼 유량을 더 흘리게 됩니다. 반대로, 시작점이 이동하면 최대 1만큼 유량을 제거하게 됩니다. 두 연산은 각각 $O(N)$번 수행하게 됩니다.</p> <p>1만큼 유량을 흘리는 것은, 간선을 추가하고 DFS를 이용해 Augmenting Path를 찾아주는 것으로 $O(N)$에 수행할 수 있습니다.<br /> 유량을 1만큼 제거하는 것은, 제거하고자 하는 정점 $v \in r$에 대해, $v$와 매칭을 이루고 있는 정점 $u \in L$을 찾아서 두 정점 사이의 유량을 제거하면 됩니다. 이 과정도 $O(N)$에 수행할 수 있습니다.</p> <p>따라서, 투포인터에서 시작점과 끝점이 각각 $O(N)$번 이동하고, 포인터가 이동할 때마다 유량의 변화를 $O(N)$에 계산할 수 있으므로 $O(N^2)$에 문제를 풀 수 있습니다.</p> <p><strong>본 대회의 시간 제한은 120초였지만 BOJ는 30초로 세팅되어 있어 상수 커팅이 필요할 수 있습니다.</strong></p> <h3 id="전체-코드">전체 코드</h3> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include &lt;bits/stdc++.h&gt; #define all(v) v.begin(), v.end() #define compress(v) sort(all(v)), v.erase(unique(all(v)), v.end()) </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="n">A</span><span class="p">[</span><span class="mi">50000</span><span class="p">][</span><span class="mi">6</span><span class="p">],</span> <span class="n">mp</span><span class="p">[</span><span class="mi">1000001</span><span class="p">];</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">C</span><span class="p">,</span> <span class="n">G</span><span class="p">[</span><span class="mi">300000</span><span class="p">],</span> <span class="n">I</span><span class="p">[</span><span class="mi">300000</span><span class="p">];</span> <span class="kt">int</span> <span class="n">P</span><span class="p">[</span><span class="mi">50000</span><span class="p">],</span> <span class="n">R</span><span class="p">[</span><span class="mi">300000</span><span class="p">],</span> <span class="n">V</span><span class="p">[</span><span class="mi">50000</span><span class="p">],</span> <span class="n">pv</span><span class="p">,</span> <span class="n">match</span><span class="p">;</span> <span class="kr">inline</span> <span class="kt">void</span> <span class="nf">addEdge</span><span class="p">(</span><span class="kt">int</span> <span class="n">s</span><span class="p">,</span> <span class="kt">int</span> <span class="n">e</span><span class="p">){</span> <span class="n">G</span><span class="p">[</span><span class="n">s</span><span class="p">].</span><span class="n">push_back</span><span class="p">(</span><span class="n">e</span><span class="p">);</span> <span class="p">}</span> <span class="kt">bool</span> <span class="nf">dfs</span><span class="p">(</span><span class="kt">int</span> <span class="n">v</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">G</span><span class="p">[</span><span class="n">v</span><span class="p">]){</span> <span class="k">if</span><span class="p">(</span><span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="n">pv</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span> <span class="n">V</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">pv</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span> <span class="o">||</span> <span class="n">dfs</span><span class="p">(</span><span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="p">])){</span> <span class="n">P</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span><span class="p">;</span> <span class="n">R</span><span class="p">[</span><span class="n">v</span><span class="p">]</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="kr">inline</span> <span class="kt">void</span> <span class="nf">insert</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">){</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">I</span><span class="p">[</span><span class="n">x</span><span class="p">])</span> <span class="n">addEdge</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span> <span class="n">pv</span><span class="o">++</span><span class="p">;</span> <span class="n">match</span> <span class="o">+=</span> <span class="n">dfs</span><span class="p">(</span><span class="n">x</span><span class="p">);</span> <span class="p">}</span> <span class="kr">inline</span> <span class="kt">void</span> <span class="nf">erase</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">R</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="n">match</span><span class="o">--</span><span class="p">,</span> <span class="n">P</span><span class="p">[</span><span class="n">R</span><span class="p">[</span><span class="n">x</span><span class="p">]]</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="n">R</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span> <span class="n">G</span><span class="p">[</span><span class="n">x</span><span class="p">].</span><span class="n">clear</span><span class="p">();</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">radixSort</span><span class="p">(){</span> <span class="c1">// radix sort for coord compress</span> <span class="k">static</span> <span class="n">queue</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">Q</span><span class="p">[</span><span class="mi">1024</span><span class="p">];</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">C</span><span class="p">)</span> <span class="n">Q</span><span class="p">[</span><span class="n">i</span> <span class="o">&amp;</span> <span class="mi">1023</span><span class="p">].</span><span class="n">push</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="n">C</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">1024</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="k">while</span><span class="p">(</span><span class="n">Q</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">size</span><span class="p">())</span> <span class="n">C</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">Q</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">front</span><span class="p">()),</span> <span class="n">Q</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">pop</span><span class="p">();</span> <span class="k">for</span><span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">:</span> <span class="n">C</span><span class="p">)</span> <span class="n">Q</span><span class="p">[</span><span class="n">i</span> <span class="o">&gt;&gt;</span> <span class="mi">10</span><span class="p">].</span><span class="n">push</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="n">C</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="mi">1024</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="k">while</span><span class="p">(</span><span class="n">Q</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">size</span><span class="p">())</span> <span class="n">C</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">Q</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">front</span><span class="p">()),</span> <span class="n">Q</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">pop</span><span class="p">();</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">Solve</span><span class="p">(){</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">N</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">6</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">],</span> <span class="n">C</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]);</span> <span class="n">radixSort</span><span class="p">();</span> <span class="n">C</span><span class="p">.</span><span class="n">erase</span><span class="p">(</span><span class="n">unique</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">C</span><span class="p">)),</span> <span class="n">C</span><span class="p">.</span><span class="n">end</span><span class="p">());</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">C</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">mp</span><span class="p">[</span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">N</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o">&lt;</span><span class="mi">6</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span> <span class="n">I</span><span class="p">[</span><span class="n">mp</span><span class="p">[</span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]]].</span><span class="n">push_back</span><span class="p">(</span><span class="n">i</span><span class="p">);</span> <span class="n">match</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">memset</span><span class="p">(</span><span class="n">P</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="o">*</span><span class="n">N</span><span class="p">);</span> <span class="n">memset</span><span class="p">(</span><span class="n">R</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="o">*</span><span class="n">C</span><span class="p">.</span><span class="n">size</span><span class="p">());</span> <span class="kt">int</span> <span class="n">l</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">r</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">mx</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="k">while</span><span class="p">(</span><span class="nb">true</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">match</span> <span class="o">==</span> <span class="n">r</span><span class="o">-</span><span class="n">l</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="n">mx</span> <span class="o">=</span> <span class="n">max</span><span class="p">(</span><span class="n">mx</span><span class="p">,</span> <span class="n">r</span><span class="o">-</span><span class="n">l</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">l</span><span class="o">+</span><span class="mi">1</span> <span class="o">==</span> <span class="n">C</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="k">break</span><span class="p">;</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">r</span><span class="o">+</span><span class="mi">1</span> <span class="o">==</span> <span class="n">C</span><span class="p">.</span><span class="n">size</span><span class="p">())</span> <span class="n">erase</span><span class="p">(</span><span class="n">l</span><span class="o">++</span><span class="p">);</span> <span class="k">else</span> <span class="k">if</span><span class="p">(</span><span class="n">l</span> <span class="o">==</span> <span class="n">r</span> <span class="o">||</span> <span class="n">match</span> <span class="o">==</span> <span class="n">r</span><span class="o">-</span><span class="n">l</span><span class="o">+</span><span class="mi">1</span><span class="p">){</span> <span class="k">if</span><span class="p">(</span><span class="n">C</span><span class="p">[</span><span class="n">r</span><span class="p">]</span><span class="o">+</span><span class="mi">1</span> <span class="o">!=</span> <span class="n">C</span><span class="p">[</span><span class="n">r</span><span class="o">+</span><span class="mi">1</span><span class="p">])</span> <span class="k">while</span><span class="p">(</span><span class="n">l</span> <span class="o">&lt;=</span> <span class="n">r</span><span class="p">)</span> <span class="n">erase</span><span class="p">(</span><span class="n">l</span><span class="o">++</span><span class="p">);</span> <span class="n">insert</span><span class="p">(</span><span class="o">++</span><span class="n">r</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="n">erase</span><span class="p">(</span><span class="n">l</span><span class="o">++</span><span class="p">),</span> <span class="n">pv</span><span class="o">++</span><span class="p">,</span> <span class="n">match</span> <span class="o">+=</span> <span class="n">dfs</span><span class="p">(</span><span class="n">r</span><span class="p">);</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">mx</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;</span><span class="n">C</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="n">G</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">clear</span><span class="p">(),</span> <span class="n">I</span><span class="p">[</span><span class="n">i</span><span class="p">].</span><span class="n">clear</span><span class="p">();</span> <span class="n">C</span><span class="p">.</span><span class="n">clear</span><span class="p">();</span> <span class="p">}</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="kt">int</span> <span class="n">T</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">T</span><span class="p">;</span> <span class="n">C</span><span class="p">.</span><span class="n">reserve</span><span class="p">(</span><span class="mi">50000</span><span class="o">*</span><span class="mi">6</span><span class="p">);</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">tc</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">tc</span><span class="o">&lt;=</span><span class="n">T</span><span class="p">;</span> <span class="n">tc</span><span class="o">++</span><span class="p">){</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">"Case #"</span> <span class="o">&lt;&lt;</span> <span class="n">tc</span> <span class="o">&lt;&lt;</span> <span class="s">": "</span><span class="p">;</span> <span class="n">Solve</span><span class="p">();</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div>JusticeHui문제 링크 http://icpc.me/14832생각나는 대로 적는 PS팁2021-03-31T12:16:00+00:002021-03-31T12:16:00+00:00https://justicehui.github.io/etc/2021/03/31/ps-tip<p>업보를 청산하기 위해 만들었습니다.<br /> <strong>어 이거 웰노운인데…</strong> / <strong>이건 당연히 아는 거 아닌가?</strong> 라는 생각이 날 때마다 추가하겠습니다.</p> <h3 id="기본적인-연산">기본적인 연산</h3> <ul> <li><code class="language-plaintext highlighter-rouge">a &lt; 0, M &gt; 0</code>일 때 <strong>a mod M</strong> = (a % M + M) % M</li> <li><code class="language-plaintext highlighter-rouge">a &gt; 0, b &gt; 0</code>일 때 <strong>a/b보다 작지 않은 최소 자연수</strong>: <code class="language-plaintext highlighter-rouge">(a-1)/b+1 = (a+b-1)/b</code></li> <li><strong>실수 오차 핸들링</strong>: 적당히 작은 상수(ex. <code class="language-plaintext highlighter-rouge">1e-7</code>)에 대해, <code class="language-plaintext highlighter-rouge">a == b</code> 대신 <code class="language-plaintext highlighter-rouge">abs(a-b) &lt; eps</code>로 비교</li> </ul> <h3 id="유명한-접근-방식">유명한 접근 방식</h3> <ul> <li><strong>가능한 최소/최대</strong>: 파라메트릭 서치 <ul> <li><strong>분수를 최소/최대화</strong>: 파라메트릭 서치 (<code class="language-plaintext highlighter-rouge">for(int i=0; i&lt;ITER; i++) go();</code>)</li> </ul> </li> <li><strong>기댓값을 최대화</strong>: DP 혹은 파라메트릭 서치 (ex. NYPC 2019 강화)</li> <li><strong>격자에서 2~3방향으로 이동</strong> + 사이클 없음: DP (3방향이면 DP 2개 관리해서 양쪽으로)</li> <li><strong>격자에서 ???의 최대/최소 개수</strong>: 이분 매칭(최소 정점 덮개, 최대 독립 집합, 최소 경로 덮개, 최대 반사슬 등)</li> <li><strong>간선을 끊는 쿼리</strong>: 순서 뒤집으면 간선을 연결하는 쿼리 = Union-Find <ul> <li><strong>구간 분할</strong>: 순서 뒤집으면 구간 병합 = Union-Find</li> </ul> </li> <li><strong>간선 정보가 바뀌는 쿼리</strong>: 쿼리를 sqrtN or sqrtQ개씩 나눠서 처리</li> <li><strong>xor 최대/최소</strong>: Trie</li> <li><strong>괄호 문자열</strong>: Stack / DP / Tree(Forest) <ul> <li>수직선 상에서 두 가지 종류의 사물을 매칭 (ex. KOI 2005 소방차)</li> </ul> </li> <li><strong>정적 트리</strong>: 트리 DP / Heavy Light Decomposition / Centroid Decomposition / 트리 압축 / 트리 이진 변환</li> <li><strong>모든 구간에 대한 ???의 합/최소/최대/개수</strong>: 분할 정복 <ul> <li><strong>트리의 모든 경로에 대한 ???의 합/최소/최대/개수</strong>: Centroid Decomposition</li> </ul> </li> <li><strong>구간을 뒤집는 연산</strong>: Splay Tree</li> </ul> <h3 id="유명한-문제--풀어보면-좋은-문제">유명한 문제 / 풀어보면 좋은 문제</h3> <ul> <li>KOI 2014 <strong>금광</strong></li> <li>APIO 2010 <strong>Commando</strong></li> <li>IOI 2014 Day2 <strong>Holiday</strong></li> <li>WF 2017 <strong>Money for Nothing</strong></li> <li>BalticOI 2009 Day1 <strong>Beetle</strong> (사수아탕)</li> <li>KOI 2016 <strong>장애물 경기</strong></li> <li>KOI 2014 <strong>버스 노선</strong></li> <li>Good Bye, BOJ 2019 <strong>최단 경로와 쿼리</strong></li> <li><a href="https://github.com/justiceHui/Unknown-To-Wellknown">justiceHui/Unknown-to-Wellknown</a> 참고</li> </ul> <h3 id="최적화-팁">최적화 팁</h3> <ul> <li>연속된 메모리에 동일한 연산을 적용하는 경우: SIMD</li> <li>캐시 히트(행렬 곱 for문 순서, Sparse Table 인덱스 순서 등)</li> <li>Mo’s Algorithm with Hilbert Curve</li> </ul>JusticeHui업보를 청산하기 위해 만들었습니다. 어 이거 웰노운인데… / 이건 당연히 아는 거 아닌가? 라는 생각이 날 때마다 추가하겠습니다.2020 천하제일 코딩대회 풀이2021-03-27T07:05:00+00:002021-03-27T07:05:00+00:00https://justicehui.github.io/sunrin-ps/2021/03/27/sunrin-icpc-2020<h3 id="잡담">잡담</h3> <p>2018, 2019년 대회는 참가를 해서 각각 2등과 1등을 했고, 2020년에는 대회 운영에 참가해 대회 현장 운영진, 문제 검수, 해설 슬라이드 작성, 문제 해설 등 다양한 업무를 담당했습니다.<br /> 이 글에서는 2020년 천하제일 코딩대회의 모든 문제의 풀이를 소개합니다.<br /> 여담으로, 해가 갈수록 문제가 점점 어려워지는데 올해(2021년) 대회는 어떤 문제가 나올지 기대가 됩니다.</p> <h3 id="예선-a번-백준-20492-세금">예선 A번) 백준 20492 세금</h3> <blockquote> <p><a href="/review/2020/09/09/brandi-code/">선린인터넷고등학교의 한 학생은 프로그래밍 대회에 참가하여 거액의 상금을 수상하는 영광을 누리게 되었다.</a></p> </blockquote> <p>전체 금액의 22%를 세금으로 납부하면 78%를 받게 됩니다.<br />전체 금액의 80%를 필요 경비를 인정하고, 나머지 부분에 대해서만 22%를 납부하면 95.6%를 받게 됩니다.</p> <p><code class="language-plaintext highlighter-rouge">N * 956 / 1000</code>처럼 계산하면 N이 <code class="language-plaintext highlighter-rouge">int</code>형일 때 overflow가 날 수도 있으니 <code class="language-plaintext highlighter-rouge">N / 1000 * 956</code>와 같이 계산하는 것을 권장합니다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include &lt;bits/stdc++.h&gt; </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="kt">int</span> <span class="n">n</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">n</span> <span class="o">/</span> <span class="mi">100</span> <span class="o">*</span> <span class="mi">78</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span> <span class="o">&lt;&lt;</span> <span class="n">n</span> <span class="o">/</span> <span class="mi">1000</span> <span class="o">*</span> <span class="mi">956</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <h3 id="예선-b번-백준-20493-세상은-하나의-손수건">예선 B번) 백준 20493 세상은 하나의 손수건</h3> <p>조건문을 열심히 코딩해도 되지만, 저는 x, y축 방향 이동을 나타내는 배열 <code class="language-plaintext highlighter-rouge">dx, dy</code>를 잡아서 구현하는 것을 선호합니다.</p> <p><code class="language-plaintext highlighter-rouge">dx, dy</code>를 시계 방향 또는 반시계 방향으로 정한 뒤, 회전 방향에 따라 <code class="language-plaintext highlighter-rouge">dir + 1 mod 4</code>와 <code class="language-plaintext highlighter-rouge">dir - 1 mod 4</code>를 적용하면 됩니다. C/C++에서는 <code class="language-plaintext highlighter-rouge">-1 % 4 == -1</code>이기 때문에 <code class="language-plaintext highlighter-rouge">(dir - 1) % 4</code> 대신 <code class="language-plaintext highlighter-rouge">(dir + 3) % 4</code>를 써야 합니다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include &lt;bits/stdc++.h&gt; </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">typedef</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">ll</span><span class="p">;</span> <span class="kt">int</span> <span class="n">dx</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span> <span class="kt">int</span> <span class="n">dy</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">};</span> <span class="n">ll</span> <span class="n">n</span><span class="p">,</span> <span class="n">t</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">n</span> <span class="o">&gt;&gt;</span> <span class="n">t</span><span class="p">;</span> <span class="n">ll</span> <span class="n">lst</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">dir</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="n">ll</span> <span class="n">now</span><span class="p">;</span> <span class="n">string</span> <span class="n">s</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">now</span> <span class="o">&gt;&gt;</span> <span class="n">s</span><span class="p">;</span> <span class="n">x</span> <span class="o">+=</span> <span class="n">dx</span><span class="p">[</span><span class="n">dir</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">now</span> <span class="o">-</span> <span class="n">lst</span><span class="p">);</span> <span class="n">y</span> <span class="o">+=</span> <span class="n">dy</span><span class="p">[</span><span class="n">dir</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">now</span> <span class="o">-</span> <span class="n">lst</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">s</span> <span class="o">==</span> <span class="s">"left"</span><span class="p">)</span> <span class="n">dir</span> <span class="o">=</span> <span class="p">(</span><span class="n">dir</span> <span class="o">+</span> <span class="mi">3</span><span class="p">)</span> <span class="o">%</span> <span class="mi">4</span><span class="p">;</span> <span class="k">else</span> <span class="n">dir</span> <span class="o">=</span> <span class="p">(</span><span class="n">dir</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="mi">4</span><span class="p">;</span> <span class="n">lst</span> <span class="o">=</span> <span class="n">now</span><span class="p">;</span> <span class="p">}</span> <span class="n">x</span> <span class="o">+=</span> <span class="n">dx</span><span class="p">[</span><span class="n">dir</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">t</span> <span class="o">-</span> <span class="n">lst</span><span class="p">);</span> <span class="n">y</span> <span class="o">+=</span> <span class="n">dy</span><span class="p">[</span><span class="n">dir</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">t</span> <span class="o">-</span> <span class="n">lst</span><span class="p">);</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">x</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span> <span class="o">&lt;&lt;</span> <span class="n">y</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <h3 id="예선-c번-백준-20494-스시">예선 C번) 백준 20494 스시</h3> <p>잘 생각해보면, 문자열의 길이의 총합이 문제의 정답이 된다는 것을 알 수 있습니다.</p> <p>C언어로 구현할 때는 <code class="language-plaintext highlighter-rouge">&lt;string.h&gt;</code>에 있는 <code class="language-plaintext highlighter-rouge">strlen</code>함수를 사용해 문자열의 길이를 구할 수 있습니다.</p> <p>문자열의 길이가 최대 100이기 때문에 배열의 길이는 최소한 <strong>101</strong> 이상으로 잡아야 합니다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include &lt;bits/stdc++.h&gt; </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="kt">int</span> <span class="n">n</span><span class="p">,</span> <span class="n">ans</span><span class="p">;</span> <span class="n">string</span> <span class="n">s</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">s</span><span class="p">;</span> <span class="n">ans</span> <span class="o">+=</span> <span class="n">s</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="p">}</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">ans</span><span class="p">;</span> <span class="p">}</span> </code></pre></div></div> <h3 id="예선-d번--백준-20495-수열과-헌팅">예선 D번) 백준 20495 수열과 헌팅</h3> <p>어떤 원소가 최대한 앞에 나오기 위해서는 (1) 자기 자신은 최대한 작아지고, (2) 다른 모든 원소는 최대한 커져야 합니다.<br />마찬가지로, 어떤 원소가 최대한 뒤에 나오기 위해서는 (1) 자기 자신은 최대한 커지고, (2) 다른 모든 원소는 최대한 작아져야 합니다.</p> <p>그러므로 어떤 원소 <code class="language-plaintext highlighter-rouge">a[x] ± b[x]</code>가 올 수 있는 가장 빠른 위치는, <code class="language-plaintext highlighter-rouge">a[i] + b[i]</code>의 값을 다 모았을 때 <code class="language-plaintext highlighter-rouge">a[x] - b[x]</code>보다 작은 수의 개수가 됩니다.<br />어떤 원소 <code class="language-plaintext highlighter-rouge">a[x] ± b[x]</code>가 올 수 있는 가장 뒤쪽 위치는, <code class="language-plaintext highlighter-rouge">a[i] - b[i]</code>의 값을 다 모았을 때 (<code class="language-plaintext highlighter-rouge">a[x] + b[x]</code>보다 작거나 같은 수의 개수) - 1입니다. (<code class="language-plaintext highlighter-rouge">a[x] - b[x]</code> 빼야함)</p> <p>이분 탐색을 이용하면 문제에서 요구하는 답을 O(N log N)만에 구할 수 있습니다.</p> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include &lt;bits/stdc++.h&gt; #define all(v) v.begin(), v.end() </span><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span> <span class="k">typedef</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">ll</span><span class="p">;</span> <span class="n">ll</span> <span class="n">n</span><span class="p">,</span> <span class="n">a</span><span class="p">[</span><span class="mi">505050</span><span class="p">],</span> <span class="n">b</span><span class="p">[</span><span class="mi">505050</span><span class="p">];</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">ll</span><span class="o">&gt;</span> <span class="n">mn</span><span class="p">,</span> <span class="n">mx</span><span class="p">;</span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="n">ios_base</span><span class="o">::</span><span class="n">sync_with_stdio</span><span class="p">(</span><span class="nb">false</span><span class="p">);</span> <span class="n">cin</span><span class="p">.</span><span class="n">tie</span><span class="p">(</span><span class="nb">nullptr</span><span class="p">);</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">n</span><span class="p">;</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="n">ll</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">;</span> <span class="n">cin</span> <span class="o">&gt;&gt;</span> <span class="n">x</span> <span class="o">&gt;&gt;</span> <span class="n">y</span><span class="p">;</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="n">y</span><span class="p">;</span> <span class="n">mn</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span><span class="p">;</span> <span class="n">mx</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span> <span class="p">}</span> <span class="n">sort</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">mn</span><span class="p">));</span> <span class="n">sort</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">mx</span><span class="p">));</span> <span class="k">for</span><span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">1</span><span class="p">;</span> <span class="n">i</span><span class="o">&lt;=</span><span class="n">n</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span> <span class="kt">int</span> <span class="n">t1</span> <span class="o">=</span> <span class="n">lower_bound</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">mx</span><span class="p">),</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">-</span> <span class="n">mx</span><span class="p">.</span><span class="n">begin</span><span class="p">()</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="kt">int</span> <span class="n">t2</span> <span class="o">=</span> <span class="n">upper_bound</span><span class="p">(</span><span class="n">all</span><span class="p">(</span><span class="n">mn</span><span class="p">),</span> <span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">-</span> <span class="n">mn</span><span class="p">.</span><span class="n">begin</span><span class="p">();</span> <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="n">t1</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span> <span class="o">&lt;&lt;</span> <span class="n">t2</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre></div></div> <h3 id="본선-a번-백준-20496-amy-soup-is-salty">본선 A번) 백준 20496 Amy, Soup is Salty!</h3> <p>(1) 현재 시간에 처리할 정보, (2) 다음 시간에 처리할 정보를 각각 큐로 관리하면서 문제에서 시키는 대로 BFS를 하면 됩니다.</p> <p>BFS를 하면서 빈 칸을 모두 방문했다면 마지막으로 방문한 시간을, 빈칸을 모두 방문하기 전에 BFS가 종료되었다면 -1을 출력하면 됩니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FA.cpp">정답 코드</a></p> <h3 id="본선-b번-백준-20497-bessies-revolution">본선 B번) 백준 20497 Bessie’s Revolution</h3> <p>어떤 칸 (r, c)에 잠복할 수 있는 조건은 다음과 같습니다.</p> <ol> <li>(r, c)가 빈 칸(‘.’)이다.</li> <li>(r, c)를 장애물(‘@’)로 바꿨을 때, (r, c)가 속한 공간이 두 개 이상으로 분할된다.</li> </ol> <p>즉, 2차원 평면에서의 단절점을 찾는 문제입니다.</p> <p>정점 개수가 적기 때문에, 모든 빈 칸을 하나씩 장애물로 바꿔보면서 해당 칸이 속한 공간이 두 개 이상으로 분할되는지 확인하면 됩니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FB.cpp">정답 코드</a></p> <h3 id="본선-c번-백준-20498-c--15">본선 C번) 백준 20498 C = 15</h3> <p><strong>족보의 힘</strong>을 사용해서 정점 몇 개가 합쳐졌을 때 트리의 지름을 빠르게 구하는 문제입니다.</p> <p>해야하는 작업은 다음과 같습니다.</p> <ol> <li>두 정점의 LCA 구하기</li> <li><strong>족보의 힘</strong>을 사용했을 때 합쳐지는 정점 처리</li> <li>일부 정점이 합쳐진 트리에서 지름 구하기</li> </ol> <p>트리의 높이가 O(log N)이기 때문에 LCA를 Naive하게 구해도 O(log N)에 구할 수 있습니다.</p> <p><strong>족보의 힘을 사용했을 때 합쳐지는 정점을 처리해봅시다.</strong></p> <p>l ~ r번째 리프를 합치는 상황을 생각해봅시다. 합쳐지는 정점을 모두 구하는 것보다는 필요 없는 정점을 제거하는 것이 편합니다. LCA(l, r)을 루트로 하는 서브 트리에서 필요 없는 정점을 제거하면 됩니다.</p> <p>필요 없는 정점은 다음 과정을 통해 제거할 수 있습니다.</p> <ol> <li>l에서 LCA(l, r)까지 부모 정점을 따라 올라가면서, l의 왼쪽 자식이 합쳐지는지 확인</li> <li>r에서 LCA(l, r)까지 부모 정점을 따라 올라가면서, r의 오른쪽 자식이 합쳐지는지 확인</li> </ol> <p>l, r의 왼쪽, 오른쪽 자식 정점이 합쳐지지 않는다면, 해당 정점을 루트로 하는 서브 트리 전체가 포함되지 않습니다.</p> <p><strong>S(v) = v를 루트로 하는 서브 트리의 가중치 합</strong>을 미리 계산해놓으면, 합쳐진 정점의 가중치를 빠르게 구할 수 잇습니다.</p> <p><strong>일부 정점이 합쳐진 트리에서 지름을 구해봅시다.</strong></p> <p>합쳐진 정점 U는 지름에 무조건 포함시킵시다.</p> <p>U를 기준으로 (1) 왼쪽, (2) 오른쪽, (3) 위에 서브트리가 있을 수 있습니다.<br />트리의 지름(∈ 경로)는 두 점을 잇는 것이기 때문에 (1), (2), (3) 중 1, 2번째로 큰 값을 U에 더한 것이 트리의 지름이 됩니다.</p> <p><strong>D(v) = v에서 리프노트까지 내려가는 경로 중 가중치의 최댓값</strong>을 미리 구해놓으면 비교적 쉽게 처리할 수 있습니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FC.cpp">정답 코드</a></p> <h3 id="본선-d번-백준-20499-darius님-한타-안-함">본선 D번) 백준 20499 Darius님 한타 안 함?</h3> <div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include &lt;stdio.h&gt; </span> <span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span> <span class="kt">int</span> <span class="n">K</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">A</span><span class="p">;</span> <span class="n">scanf</span><span class="p">(</span><span class="s">"%d/%d/%d"</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">K</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">D</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">A</span><span class="p">);</span> <span class="k">if</span><span class="p">(</span><span class="n">K</span><span class="o">+</span><span class="n">A</span> <span class="o">&lt;</span> <span class="n">D</span> <span class="o">||</span> <span class="n">D</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="n">printf</span><span class="p">(</span><span class="s">"hasu"</span><span class="p">);</span> <span class="k">else</span> <span class="n">printf</span><span class="p">(</span><span class="s">"gosu"</span><span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <h3 id="본선-e번-백준-20500-ezreal-여눈부터-가네-ㅈㅈ">본선 E번) 백준 20500 Ezreal 여눈부터 가네 ㅈㅈ</h3> <p>15의 배수는 3의 배수인 동시에 5의 배수인 수입니다.<br />5의 배수는 마지막 자리가 0 또는 5인 수이며, 3의 배수는 각 자리 수의 합이 3의 배수인 수입니다. 두 조건이 성립하는 수의 개수를 구하면 됩니다.</p> <p>마지막 자리에는 5 밖에 올 수 없기 때문에, 나머지 N-1자리를 적절히 배정해서 3의 배수로 만들면 됩니다.<br />즉, N-1개의 합을 3으로 나눈 나머지가 1이 되도록 만들면 됩니다.</p> <p>1을 a개, 5를 b개 사용한다고 합시다. 아래 두 조건을 만족해야 합니다.</p> <ol> <li>a + b = N-1</li> <li>(a + 5b)를 3으로 나눈 나머지가 1 = (a + 2b)를 3으로 나눈 나머지가 1</li> </ol> <p>(a, b)가 두 조건을 만족한다면, N-1개 중 a개는 0을 배정하고, 나머지는 1로 배정하면 됩니다.<br />N-1개 중 a개를 고르는 경우는 (N-1)Ca 입니다. 두 조건을 만족하는 모든 (a, b) 쌍에 대해 (N-1)Ca 의 합을 구해서 출력하면 됩니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FE.cpp">정답 코드</a></p> <h3 id="본선-f번-백준-20501-facebook">본선 F번) 백준 20501 Facebook</h3> <p>친구 관계를 그래프로 모델링합시다. a, b와 동시에 이웃한 정점의 개수를 구하면 됩니다.<br />이를 구하는 가장 간단한 풀이는, A[a, i]와 A[b, i]가 동시에 1인 i를 세는 것입니다.</p> <p>이 풀이는 시간 복잡도가 O(NQ)로 시간 초과를 받게 됩니다. 이 풀이를 최적화 해봅시다.</p> <p>N이 32 이하라면 한 사람의 친구 관계를 int형(32비트 정수) 변수 하나로 관리할 수 있습니다. 이때 a, b와 동시에 이웃한 정점은 두 정수에 and 연산을 취한 값에서 켜진 비트의 개수가 됩니다.</p> <p>그러므로 친구 관계를 N/32개의 int형 변수로 관리해주면 연산량을 32배 줄일 수 있습니다. long long형(64비트 정수)을 사용하면 64배 줄일 수 있습니다.</p> <p>이런 테크닉을 bitset이라고 부릅니다. 시간 복잡도는 O(NQ/64)가 됩니다.</p> <p>C/C++에서 gcc 컴파일러를 쓰는 경우, 정수 자료형에서 켜진 비트의 개수를 빠르게 구해주는 함수가 있어, 이 함수를 이용하면 편하게 구현할 수 있습니다. int형은 <code class="language-plaintext highlighter-rouge">__builtin_popcount</code>, long long형은 <code class="language-plaintext highlighter-rouge">__builtin_popcountll</code>을 사용하면 됩니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FF.cpp">정답 코드</a></p> <h3 id="본선-g번-백준-20502-gum색">본선 G번) 백준 20502 Gum색</h3> <p>배열 A[i]를 키워드 i를 포함하는 컨텐츠의 번호라고 정의합시다.</p> <p>각 배열의 원소를 잘 정렬해서 출력하면 됩니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FG.cpp">정답 코드</a></p> <h3 id="본선-h번-백준-20503-haven">본선 H번) 백준 20503 Haven</h3> <p>주어진 문제를 반대로 생각해서, Xi들이 주어졌을 때 MST를 구하는 문제를 생각해봅시다.</p> <p>28번째 비트가 켜져있는 정점들의 집합과 꺼져있는 정점들의 집합을 잇는 간선은 하나만 존재하는 것이 최적입니다. 정점 집합을 28번째 비트에 따라서 분할합시다.</p> <p>28번째 비트에 따라 분할된 각 집합 안에서, 27번째 비트가 켜져있는 정점들의 집합과 꺼져있는 정점들의 집합을 잇는 간선은 하나만 존재하는 것이 최적입니다. 이 정점 집합을 다시 27번째 비트에 따라서 분할합니다.</p> <p>위 과정을 반복하는 것으로 MST를 구할 수 있습니다.<br />이 풀이를 응용해 MST가 주어졌을 때 Xi를 복원하는 방법을 생각해봅시다.</p> <p>f(T, D)를 트리 T의 각 정점을 2^(D+1) 미만의 수로 채우는 함수라고 합시다.</p> <p>T에서 적당한 간선 (u, v)를 잡아서 끊으면 트리가 두 개로 분할됩니다. 분할된 각 트리를 T1, T2라고 합시다.<br />아래 과정을 거쳐 Xi를 복원할 수 있습니다.</p> <ol> <li>T1에 속한 정점의 D번째 비트를 0으로 설정</li> <li>T2에 속한 정점의 D번째 비트를 1로 설정</li> <li>f(T1, D-1)과 f(T2, D-1)을 각각 재귀적으로 호출</li> <li>두 트리 T1과 T2를 분할하는 간선 (u, v)가 T1과 T2를 연결하는 최소 가중치 간선이 되도록 T1과 T2의 각 정점에 적절한 값을 xor</li> </ol> <p>트리의 degree가 3 이하라면 아래 조건을 만족하는 간선 e가 반드시 존재한다고 합니다.</p> <ul> <li>e를 제거해서 만들어진 트리를 T1, T2, 각 트리에 속한 정점의 개수를 S1, S2라고 할 때</li> <li>S2 ≤ 2 × S1 + 1, S1 ≤ 2 × S2 + 1</li> </ul> <p>이 조건 덕분에 분할 정복은 최대 28단계 안에 작동합니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FH.cpp">정답 코드</a></p> <h3 id="본선-i번-백준-20504-i번은-쉬운-문제">본선 I번) 백준 20504 I번은 쉬운 문제</h3> <p>함수의 호출 관계는 방향 그래프로 표현할 수 있습니다.</p> <p>모든 함수를 호출하기 위해 호출해야하는 함수의 최소 개수는 <strong>in-degree가 0인 SCC의 개수</strong>와 동일합니다.</p> <p>테스트 케이스로 주어진 T개의 함수가 in-degree가 0인 SCC를 모두 커버하는지 확인하면 됩니다.<br />모두 커버한다면 in-degree가 0인 SCC의 개수를, 모두 커버하지 않는다면 -1을 출력하면 됩니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FI.cpp">정답 코드</a></p> <h3 id="본선-j번-백준-20505-johns-math-problem">본선 J번) 백준 20505 John’s Math Problem</h3> <p>입력으로 주어진 수를 A0 A1 A2 … A(n-1)이라고 합시다.<br />Ai가 답에 얼마나 기여하는지 알면 문제의 정답을 구할 수 있습니다. 구체적으로, Ai가 1의 자리가 되는 경우의 수, 10의 자리가 되는 경우의 수, 100의 자리가 되는 경우의 수, …를 구하면 됩니다.</p> <p>Ai가 10^r자리가 되는 경우의 수는 다음과 같이 계산할 수 있습니다.</p> <ul> <li>Ai보다 뒤에 있는 n-i-1개의 수는 정확히 r개 포함해야 합니다. 이런 경우의 수는 (n-i-1)Cr입니다.</li> <li>Ai보다 앞에 있는 i개의 수는 포함 여부를 고려할 필요가 없습니다. 2^i 가지 경우의 수를 모두 포함하며 됩니다.</li> <li>그러므로 Ai가 10^r자리가 되는 경우의 수는 2^i × (n-i-1)Cr입니다.</li> </ul> <p>Ai는 답에 2^i × sum((n-i-1)Cr)만큼 기여하게 됩니다. 이때 r는 0부터 n-i-1까지의 정수입니다.<br />이항 정리에 의해 sum((n-i-1)Cr)은 11^(n-i-1)이 됩니다.</p> <p>따라서 Ai는 답에 Ai × 2^i × 11^(n-i-1)만큼 기여합니다.</p> <p>모든 i에 대해 구해서 더해주면 됩니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FJ.cpp">정답 코드</a></p> <h3 id="본선-k번-백준-20506-kaisar---생존">본선 K번) 백준 20506 Kaisar - 생존</h3> <p>“각 정점이 LCA가 되는 경우의 수”를 구하면 답은 쉽게 구할 수 있습니다.</p> <p>정점 v가 LCA가 되는 경우의 수는 (v를 루트로 하는 서브 트리의 크기)^2 - sum( (v의 i번째 자식을 루트로 하는 서브 트리의 크기)^2 )입니다.</p> <p><a href="https://github.com/justiceHui/Sunrin-Contest/blob/main/Sunrin-ICPC-2020/FK.cpp">정답 코드</a></p>JusticeHui잡담 2018, 2019년 대회는 참가를 해서 각각 2등과 1등을 했고, 2020년에는 대회 운영에 참가해 대회 현장 운영진, 문제 검수, 해설 슬라이드 작성, 문제 해설 등 다양한 업무를 담당했습니다. 이 글에서는 2020년 천하제일 코딩대회의 모든 문제의 풀이를 소개합니다. 여담으로, 해가 갈수록 문제가 점점 어려워지는데 올해(2021년) 대회는 어떤 문제가 나올지 기대가 됩니다.