<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>KimHwon</title>
    <link>https://kimhwon.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 23 Aug 2026 22:09:38 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>hwon233</managingEditor>
    <item>
      <title>Docker container 외부 접근</title>
      <link>https://kimhwon.tistory.com/47</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/a/70870535&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/a/70870535&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1685254682771&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Docker Desktop for Windows: cannot access service on exposed port in windows container mode&quot; data-og-description=&quot;I am using the following Dockerfiles to create a container running Jenkins in a windows container on Windows 10 desktop running Docker Desktop for Windows version 17.03 FROM microsoft/windowsserve...&quot; data-og-host=&quot;stackoverflow.com&quot; data-og-source-url=&quot;https://stackoverflow.com/a/70870535&quot; data-og-url=&quot;https://stackoverflow.com/questions/43769806/docker-desktop-for-windows-cannot-access-service-on-exposed-port-in-windows-con&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/XEQTa/hySNjdwv7z/A6yJDnEpaSwikWmHkBI9EK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316,https://scrap.kakaocdn.net/dn/my7Ec/hySLDkmUF4/EIf3GkeKyV2lGdA1HfVfH0/img.png?width=1045&amp;amp;height=704&amp;amp;face=0_0_1045_704&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/a/70870535&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://stackoverflow.com/a/70870535&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/XEQTa/hySNjdwv7z/A6yJDnEpaSwikWmHkBI9EK/img.png?width=316&amp;amp;height=316&amp;amp;face=0_0_316_316,https://scrap.kakaocdn.net/dn/my7Ec/hySLDkmUF4/EIf3GkeKyV2lGdA1HfVfH0/img.png?width=1045&amp;amp;height=704&amp;amp;face=0_0_1045_704');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Docker Desktop for Windows: cannot access service on exposed port in windows container mode&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I am using the following Dockerfiles to create a container running Jenkins in a windows container on Windows 10 desktop running Docker Desktop for Windows version 17.03 FROM microsoft/windowsserve...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;stackoverflow.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Netsh로 proxy 연결해주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kimhwon.tistory.com/46&quot;&gt;아님 IIS로 proxy server를 구축할 수도 있고...&lt;/a&gt;&lt;/p&gt;</description>
      <category>docker</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/47</guid>
      <comments>https://kimhwon.tistory.com/47#entry47comment</comments>
      <pubDate>Sun, 28 May 2023 15:19:11 +0900</pubDate>
    </item>
    <item>
      <title>IIS reverse proxy를 사용해 Docker container에 SSL 적용하기</title>
      <link>https://kimhwon.tistory.com/46</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. IIS 설치&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.google.com/search?q=windows+10+IIS&quot;&gt;https://www.google.com/search?q=windows+10+IIS&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1685250262976&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;  windows 10 IIS: Google 검색&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.google.com&quot; data-og-source-url=&quot;https://www.google.com/search?q=windows+10+IIS&quot; data-og-url=&quot;https://www.google.com/knowledgegraphshares?q=windows+10+IIS&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bR3LJ4/hySLDxUSMw/ihTK5VGjTjqaUqXzXPwDs1/img.png?width=250&amp;amp;height=250&amp;amp;face=0_0_250_250,https://scrap.kakaocdn.net/dn/bfZrxO/hySNgHQHeG/UkACEmAeELTKfuIkUI6kk1/img.png?width=250&amp;amp;height=250&amp;amp;face=0_0_250_250&quot;&gt;&lt;a href=&quot;https://www.google.com/search?q=windows+10+IIS&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.google.com/search?q=windows+10+IIS&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bR3LJ4/hySLDxUSMw/ihTK5VGjTjqaUqXzXPwDs1/img.png?width=250&amp;amp;height=250&amp;amp;face=0_0_250_250,https://scrap.kakaocdn.net/dn/bfZrxO/hySNgHQHeG/UkACEmAeELTKfuIkUI6kk1/img.png?width=250&amp;amp;height=250&amp;amp;face=0_0_250_250');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;  windows 10 IIS: Google 검색&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IIS는 Proxy server로만 사용할 것이기 때문에 [&lt;b&gt;인터넷 정보 서비스 &amp;gt; World Wide Web &amp;gt; 응용 프로그램 개발 기능&lt;/b&gt;] 항목은 전부 선택하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2. SSL 인증서 발급&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.google.com/search?q=iis+let%27s+encrypt&quot;&gt;https://www.google.com/search?q=iis+let%27s+encrypt&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1685250771874&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;  iis let's encrypt: Google 검색&quot; data-og-description=&quot;&quot; data-og-host=&quot;www.google.com&quot; data-og-source-url=&quot;https://www.google.com/search?q=iis+let%27s+encrypt&quot; data-og-url=&quot;https://www.google.com/knowledgegraphshares?q=iis+let%27s+encrypt&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kO46m/hySNcenDQ7/rOvdeigk3InebmwEmJVvvK/img.png?width=250&amp;amp;height=250&amp;amp;face=0_0_250_250,https://scrap.kakaocdn.net/dn/dKZLDE/hySLEwNFvW/Sv8IT0BK2KDlXxvcrfWre0/img.png?width=250&amp;amp;height=250&amp;amp;face=0_0_250_250&quot;&gt;&lt;a href=&quot;https://www.google.com/search?q=iis+let%27s+encrypt&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.google.com/search?q=iis+let%27s+encrypt&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kO46m/hySNcenDQ7/rOvdeigk3InebmwEmJVvvK/img.png?width=250&amp;amp;height=250&amp;amp;face=0_0_250_250,https://scrap.kakaocdn.net/dn/dKZLDE/hySLEwNFvW/Sv8IT0BK2KDlXxvcrfWre0/img.png?width=250&amp;amp;height=250&amp;amp;face=0_0_250_250');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;  iis let's encrypt: Google 검색&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.google.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;win-acme을 사용하여 &lt;a href=&quot;https://letsencrypt.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Let's Encrypt&lt;/a&gt; 에서 SSL 인증서를 발급받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. IIS Reverse proxy 설정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://chongkong.github.io/iis-reverse-proxy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://chongkong.github.io/iis-reverse-proxy&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1685251024481&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;IIS에서 Reverese Proxy 설정하기 &amp;middot; chongkong blog&quot; data-og-description=&quot;IIS에서 Reverese Proxy 설정하기 03 Dec 2016 Slack에 interactive button을 추가하기 위해서는 Slack에서 버튼 클릭 이벤트를 전달할 수 있는 endpoint가 필요하다. 이를 request_url이라 하는데 반드시 https url을 주&quot; data-og-host=&quot;chongkong.github.io&quot; data-og-source-url=&quot;https://chongkong.github.io/iis-reverse-proxy&quot; data-og-url=&quot;https://chongkong.github.io/iis-reverse-proxy&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bjkTbE/hySM6Zw2JG/8u0sj4XM6B00orfUpqjqc1/img.png?width=2342&amp;amp;height=1105&amp;amp;face=0_0_2342_1105,https://scrap.kakaocdn.net/dn/ezD5Np/hySNhtdrFH/gbBUSmXCYsaMAfEjD0jZJK/img.png?width=642&amp;amp;height=648&amp;amp;face=0_0_642_648,https://scrap.kakaocdn.net/dn/bRUB2J/hySNir7HbX/W3eXWkj0UZdpifei8TvGt0/img.png?width=757&amp;amp;height=513&amp;amp;face=0_0_757_513&quot;&gt;&lt;a href=&quot;https://chongkong.github.io/iis-reverse-proxy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://chongkong.github.io/iis-reverse-proxy&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bjkTbE/hySM6Zw2JG/8u0sj4XM6B00orfUpqjqc1/img.png?width=2342&amp;amp;height=1105&amp;amp;face=0_0_2342_1105,https://scrap.kakaocdn.net/dn/ezD5Np/hySNhtdrFH/gbBUSmXCYsaMAfEjD0jZJK/img.png?width=642&amp;amp;height=648&amp;amp;face=0_0_642_648,https://scrap.kakaocdn.net/dn/bRUB2J/hySNir7HbX/W3eXWkj0UZdpifei8TvGt0/img.png?width=757&amp;amp;height=513&amp;amp;face=0_0_757_513');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;IIS에서 Reverese Proxy 설정하기 &amp;middot; chongkong blog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;IIS에서 Reverese Proxy 설정하기 03 Dec 2016 Slack에 interactive button을 추가하기 위해서는 Slack에서 버튼 클릭 이벤트를 전달할 수 있는 endpoint가 필요하다. 이를 request_url이라 하는데 반드시 https url을 주&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;chongkong.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.1. Application Request Routing과 URL Rewrite 모듈 설치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.iis.net/downloads/microsoft/application-request-routing&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Application Request Routing 링크&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.iis.net/downloads/microsoft/url-rewrite&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;URL Rewrite 링크&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.2. Proxy 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DESKTOP 홈 &amp;gt; Application Request Routing Cache &amp;gt; Server Proxy Settings&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Enable proxy 체크&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.3. Port 설정&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3.1. IIS 바인딩&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Web Site 홈 &amp;gt; 바인딩&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부에 공개할 포트 바인딩을 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;예시로, Docker container의 &lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;8000&lt;/span&gt;번&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;포트가 expose 되어 있고, 내 도메인네임이 &lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;my.example.com&lt;/span&gt;일 때 외부 포트 &lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;8080&lt;/span&gt;으로 접속하려면 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1685254075892&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;종류:        IP주소:                    포트:
  [https]     [지정하지 않은 모든 IP]      [8080]
호스트 이름:
  [my.example.com]
  [v] 서버 이름 표시 필요

SSL 인증서:
  [Let's Encrypt에서 발급한 인증서]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;외부 포트를 도커에서 사용하는 포트와 같은 포트로 하면 충돌하기 때문에 다른 포트를 지정해야 한다. 차후 URL Rewrite로 연결할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3.2. 방화벽 설정&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;제어판 &amp;gt; 시스템 및 보안 &amp;gt; Windows Defender 방화벽 &amp;gt; 고급 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는, '&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;고급 보안이 포함된 Windows Defender 방화벽&lt;/span&gt;' 검색 후 열기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/windows/security/operating-system-security/network-security/windows-firewall/create-an-inbound-port-rule&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learn.microsoft.com/ko-kr/windows/security/operating-system-security/network-security/windows-firewall/create-an-inbound-port-rule&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1685252136726&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;인바운드 포트 규칙 만들기&quot; data-og-description=&quot;그룹 정책 Management MMC 스냅인을 사용하여 고급 보안이 있는 Windows Defender 방화벽에서 규칙을 만들어 특정 포트에서 트래픽을 허용하는 방법을 알아봅니다.&quot; data-og-host=&quot;learn.microsoft.com&quot; data-og-source-url=&quot;https://learn.microsoft.com/ko-kr/windows/security/operating-system-security/network-security/windows-firewall/create-an-inbound-port-rule&quot; data-og-url=&quot;https://learn.microsoft.com/ko-kr/windows/security/operating-system-security/network-security/windows-firewall/create-an-inbound-port-rule&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b6thEu/hySLwFxXCI/77yKQ2WK38PqzrkIsVDSE1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/windows/security/operating-system-security/network-security/windows-firewall/create-an-inbound-port-rule&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://learn.microsoft.com/ko-kr/windows/security/operating-system-security/network-security/windows-firewall/create-an-inbound-port-rule&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b6thEu/hySLwFxXCI/77yKQ2WK38PqzrkIsVDSE1/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;인바운드 포트 규칙 만들기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;그룹 정책 Management MMC 스냅인을 사용하여 고급 보안이 있는 Windows Defender 방화벽에서 규칙을 만들어 특정 포트에서 트래픽을 허용하는 방법을 알아봅니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;learn.microsoft.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 바인딩한 포트들에 대해서 방화벽을 연다. TCP 80과 443은 IIS를 설치하면서 인바운드 규칙이 자동으로 등록되지만, Proxy port는 직접 등록해야 한다. 8080 포트에 대한 인바운드 규칙을 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3.4. Reverse proxy 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Web Site 홈 &amp;gt; URL 재작성 &amp;gt; 규칙 추가 &amp;gt; 역방향 프록시&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인바운드 규칙 서버 이름은, 로컬호스트의 docker container port&amp;nbsp;기입.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아웃바운드 규칙의 &lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;HTTP 응답의 링크 도메인 이름 재작성&lt;/span&gt; 체크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시작에는 위의 인바운드 규칙 서버 이름을, 끝에는 외부에서 접속할 Domain name을 기입.&lt;/p&gt;
&lt;pre id=&quot;code_1685252913548&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;인바운드 규칙
  HTTP 요청이 전달되면 서버 이름 또는 IP 주소 입력:
    [localhost:8000]

아웃바운드 규칙
  [v] HTTP 응답의 링크 도메인 이름 재작성
  
  시작:
    [localhost:8000]
  끝:
    [my.example.com]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;URL 재작성의 &lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;인바운드 규칙&lt;/span&gt;과 &lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아웃바운드 규칙&lt;/span&gt;이 하나씩 생성된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추가된 인바운드 규칙 &amp;gt; 편집 &amp;gt; 조건&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1685253206614&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;조건 입력:
  [{SERVER_PORT}]

패턴:
  [8080]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;{SERVER_PORT}&lt;/span&gt;는 &lt;i&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/iis/web-dev-reference/server-variables&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;IIS 서버 변수&lt;/a&gt;&lt;/i&gt; 중 하나로, 요청이 전송된 포트 번호를 저장하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;URL 검색 패턴으로는 포트 번호를 사용한 proxy 지정을 할 수 없으므로, 기본 패턴으로 그대로 두고 조건 구문을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추가된 아웃바운드 규칙 &amp;gt; 편집 &amp;gt; 작업&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1685253471076&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;작업 속성
  값:
    [http{R:1}//my.example.com:8080/{R:2}]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;URL Rewrite할 값을 지정한다. 외부로 나갈 호스트네임에 외부 포트를 추가하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하자면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인바운드 규칙에서, 모든 URL에 대하여 (8080 포트를 사용하는 경우만) localhost:8000으로 재작성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아웃바운드 규칙에서, 8080 포트를 통해 응답을 재작성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 자세한 설정 사항은 &lt;i&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/url-rewrite-module-configuration-reference&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;레퍼런스&lt;/a&gt;&lt;/i&gt;를&amp;nbsp;참조해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 서버 재시작&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;DESKTOP 홈 &amp;gt;&lt;span&gt; 서버 관리 &amp;gt; 다시 시작&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>docker</category>
      <category>https</category>
      <category>IIS</category>
      <category>proxy</category>
      <category>reverse_proxy</category>
      <category>ssl</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/46</guid>
      <comments>https://kimhwon.tistory.com/46#entry46comment</comments>
      <pubDate>Sun, 28 May 2023 15:15:22 +0900</pubDate>
    </item>
    <item>
      <title>Educational Codeforces Round 113 (Rated for Div. 2)</title>
      <link>https://kimhwon.tistory.com/44</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1155&quot; data-origin-height=&quot;105&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sR1Zj/btreyfCQoqP/vBjyjaKEexExb2cTLsmTAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sR1Zj/btreyfCQoqP/vBjyjaKEexExb2cTLsmTAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sR1Zj/btreyfCQoqP/vBjyjaKEexExb2cTLsmTAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsR1Zj%2FbtreyfCQoqP%2FvBjyjaKEexExb2cTLsmTAk%2Fimg.png&quot; data-origin-width=&quot;1155&quot; data-origin-height=&quot;105&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 컨디션이 좋다. 실력이 늘은건지 웰노운이 나온건지 잘 모르겠지만 암튼 계속 올라서 좋긴 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;A. Balanced Substring&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;a의 개수와 b의 개수가 같은 substring을 찾는 문제이다. 문자열 &quot;ab&quot; 또는 &quot;ba&quot;는 항상 조건에 맞기 때문에, 그냥 주어진 문자열에서 &quot;ab&quot; 또는 &quot;ba&quot;가 있는지만 판별하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;놀랍게도 완탐을 돌리다 TLE 맞고 틀렸다. n이 작길래 무지성으로 냈는데 다시 찬찬히 계산해보니 1e9가 넘더라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;B. Chess Tournament&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;참여자들을 정점으로 하는 그래프로 모델링하면 완전 그래프가 만들어진다. 1번 타입의 참가자는 절대 지면 안된다. 따라서 1번 타입 참가자에 연결된 간선들을 모두 지운다. 이제 남은 간선들을 가지고 2번 타입 참가자들을 연결해보자. 2번 타입 참가자들은 최소 1번만 이기면 된다. 즉, outdegree가 1 이상이 되도록 만들어야 한다. 완전 그래프기 때문에, 항상 &lt;span style=&quot;color: #222222;&quot;&gt;2번 타입 참가자들을 잇는 단순 사이클이 만들어 질 수 있다. 아래 그림은 세 번째 테스트케이스의 풀이이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1008&quot; data-origin-height=&quot;312&quot; width=&quot;604&quot; height=&quot;187&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dRxPfs/btrewxcZFkv/3T8KNRkvlAkWE1H4qzcGPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dRxPfs/btrewxcZFkv/3T8KNRkvlAkWE1H4qzcGPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dRxPfs/btrewxcZFkv/3T8KNRkvlAkWE1H4qzcGPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdRxPfs%2FbtrewxcZFkv%2F3T8KNRkvlAkWE1H4qzcGPK%2Fimg.png&quot; data-origin-width=&quot;1008&quot; data-origin-height=&quot;312&quot; width=&quot;604&quot; height=&quot;187&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 사이클이 만들어지지 않는 경우는, &lt;span style=&quot;color: #222222;&quot;&gt;2번 타입 참가자가 2명 이하인 경우이다. 한편 &lt;span style=&quot;color: #222222;&quot;&gt;2번 타입 참가자가 0명이라면 모든 참가자들이 서로 비기기만 하면 된다.(첫 번째 테스트케이스) 따라서 &lt;span style=&quot;color: #222222;&quot;&gt;2번 타입 참가자가 1명이나 2명인 경우만 NO이고 나머지 모든 경우는 YES이다. YES라면, 앞에서 설명한 대로 단순 사이클을 만들고 그 사이클에 포함되는 간선을 제외한 모든 간선을 비기는 경우로 지정하면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;C. Jury Meeting&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;nice하지 않은 경우를 생각해보자. 문제에 제시된 예시들을 잘 관찰해보면 다음과 같은 규칙을 찾을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;수열 $a$에서 가장 큰 원소를 $a_k$라고 하자. $a_k$와 값이 같은 원소가 더 있다면, 항상 nice하다.&lt;/li&gt;
&lt;li&gt;값이 $a_k - 1$인 원소가 하나도 없다면 항상 nice하지 않다.&lt;/li&gt;
&lt;li&gt;$a_k$ 이후에 값이 $a_k - 1$인 원소가 하나도 없다면 항상 nice하지 않다. 즉, $p$에 따라 $a$를 재배열했을 때, 구간 (k, n] 안의 모든 $i$에 대하여 $a_i &amp;lt; a_k - 1$이면 항상 nice하지 않다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 경우는 항상 nice하므로 $n!$이 답이다. 두 번째 경우는 항상 nice하지 않으므로 0이 답이다. 세 번째 경우를 잘 계산해야 하는데, 값이 $a_k - 2$보다 작은 원소가 $l$개라고 하면 다음과 같이 계산할 수 있다. $$ n! - \sum_{i=0}^l (n-i-1)! {k \choose i} i! $$ 팩토리얼은 오프라인으로 미리 계산해 둘 수 있고, combination은 &lt;i&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11401&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;페르마의 소정리와 분할정복&lt;/a&gt;&lt;/i&gt;을 통해 O(log n)에 계산할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 조합론 문제는 어렵다. 예제가 굉장히 잘 나와있어서 겨우 규칙을 관찰해 낼 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;D. Inconvenient Pairs&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;불편한 쌍이 만들어지는 조건은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;교차로 위에 있는 사람은 항상 불편한 쌍을 만들 수 없다.&lt;/li&gt;
&lt;li&gt;같은 열에 있는 가로 도로에 있으면서 서로 다른 도로에 있는 두 사람은 항상 불편한 쌍이다.&lt;/li&gt;
&lt;li&gt;같은 행에 있는 세로 도로에 있으면서 서로 다른 도로에 있는 두 사람은 항상 불편한 쌍이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 세로 도로와 사람들을 x좌표에 대하여 정렬한다. 이를 스위핑하면 같은 열에 있는 사람들을 골라낼 수 있다. 예를 들어 두 번째 테스트 케이스에서 1, 6, 7번 사람이 한 그룹, 8번 사람이 다른 한 그룹으로 분류된다. 이 골라낸 그룹을 이번엔 y좌표로 정렬한다. 그러면 한 그룹 내에서 같은 가로 도로에 있는 사람의 수를 찾아낼 수 있다. 현재 그룹의 크기를 $n$이고 같은 도로에 있는 사람이 $k$명이면 $\frac{\sum k(n-k)}{2}$이 불편한 쌍의 개수다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 방식으로 y좌표에 대하여 한 번 더 하면 된다.&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/44</guid>
      <comments>https://kimhwon.tistory.com/44#entry44comment</comments>
      <pubDate>Thu, 9 Sep 2021 16:38:11 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #742 (Div. 2)</title>
      <link>https://kimhwon.tistory.com/43</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1464&quot; data-origin-height=&quot;106&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JIcvV/btreibGSudN/QCVG4aV3japkePGG6BIYp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JIcvV/btreibGSudN/QCVG4aV3japkePGG6BIYp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JIcvV/btreibGSudN/QCVG4aV3japkePGG6BIYp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJIcvV%2FbtreibGSudN%2FQCVG4aV3japkePGG6BIYp1%2Fimg.png&quot; data-origin-width=&quot;1464&quot; data-origin-height=&quot;106&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역대급 퍼포먼스다. 원래 carrot은 잘라내고 캡쳐해오는데 오늘은 좀 자랑하고 싶어서 다 나오게 찍었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A. &lt;span style=&quot;color: #222222;&quot;&gt;Domino Disaster&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입력된 문자열의 각 문자에 따라 출력할 문자가 1대1로 대응된다. U이면 D, L이면 L, R이면 R로 대응해서 출력하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;B. MEXor Mixup&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;MEX 결과가 a라는 것은, [0, a) 범위의 모든 정수가 이미 수열 내에 존재한다는 뜻이다. 오프라인으로 일단 0~3e5 까지 xor한 결과를 저장해 둔다. a-1까지 xor한 결과를 가지고 b와 비교해볼 수 있다. 만약 $xored[a-1] = b$라면 a가 답이다. $xored[a-1] \ne b$ 라면 &lt;span style=&quot;color: #222222;&quot;&gt;$xored[a-1] \oplus b$&lt;/span&gt;&lt;span style=&quot;color: #222222;&quot;&gt;을 추가하면&lt;span style=&quot;color: #222222;&quot;&gt; b가 나오기 때문에 a+1이 답이다. 그런데 &lt;span style=&quot;color: #222222;&quot;&gt;$xored[a-1] \oplus b$가 a와 같을 수 있다. 그렇다면 임의의 x에 대하여 &lt;span style=&quot;color: #222222;&quot;&gt;$xored[a-1] \oplus b \oplus x$와 $x$를 수열에 추가하면 된다. 이 때 답은 a+2이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;C. Carrying Conundrum&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;brute force로 해결될 수도 있을 것 같은데, 그냥 무지성 경우의 수 DP를 사용했다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #1d1c1d;&quot;&gt;$dp[i][bit] = (i\text{번째 자리까지 덧셈을 했을때, 자리올림이 }bit)$으로 정의한다. 자리 올림을 2bit로 들고 다니면서 관리해주고, 1의 자리부터 1e9의 자리까지 처리해주면 된다. 이 때, (0, n), (n, 0)인 순서쌍도 세지므로 dp 결과에 -2를 하면 답이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #1d1c1d;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;E. Non-Decreasing Dilemma&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아주 전형적인 세그먼트 트리 문제이다. 흔히 알려진 테크닉인 &lt;i&gt;&lt;a href=&quot;https://m.blog.naver.com/edenooo/221415337560&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;금광세그&lt;/a&gt;&lt;/i&gt;를 풀어봤다면 쉽게 풀이를 떠올렸을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세그먼트 트리의 노드를 다음과 같은 6개의 원소를 가진 struct로 정의하자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ans : 이 구간에서 단조증가하는 subarray의 개수. 즉, 구간쿼리의 답&lt;/li&gt;
&lt;li&gt;sz : 이 구간의 길이&lt;/li&gt;
&lt;li&gt;lval : 이 구간의 왼쪽 끝 원소의 값&lt;/li&gt;
&lt;li&gt;lsz : 이 구간의 왼쪽 끝 원소를 포함하는 subarray의 길이&lt;/li&gt;
&lt;li&gt;rval : 이 구간의 오른쪽 끝 원소의 값&lt;/li&gt;
&lt;li&gt;rsz : 이 구간의 오른쪽 끝 원소를 포함하는 subarray의 길이&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 트리의 leaf에서는 ans = 1이고, lval = rval, sz = lsz = rsz이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1155&quot; data-origin-height=&quot;338&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cRmgfT/btrelRhqA5n/b0KyADCJKemkbKgNjIZKfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cRmgfT/btrelRhqA5n/b0KyADCJKemkbKgNjIZKfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cRmgfT/btrelRhqA5n/b0KyADCJKemkbKgNjIZKfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcRmgfT%2FbtrelRhqA5n%2Fb0KyADCJKemkbKgNjIZKfk%2Fimg.png&quot; data-origin-width=&quot;1155&quot; data-origin-height=&quot;338&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 서브노드 left와 right가 합쳐질 때 위 그림과 같이 두 가지 경우가 존재할 수 있다. 그림에서 초록색 박스는 left 노드, 파란색 박스는 right 노드이다. 노란색은 각 노드가 커버하는 구간에서 subarray이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째로 $left.rval &amp;gt; right.lval$인 경우이다.(빨강색 박스) 이 때, left의 오른쪽 끝 subarray(노란색 r) 과 right의 왼쪽 끝 subarray(노란색 l)은 그대로 나열된다. 따라서, $ret.ans = left.ans + right.ans$이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째로 $left.rval \leq right.lval$인 경우이다.(하늘색 박스) 이 때, left의 오른쪽 끝 subarray(노란색 r) 과 right의 왼쪽 끝 subarray(노란색 l)은 merge된다. 즉, 이전에 존재했던 두 subarray를 제외하고, 새로 생긴 subarray(노란색 r+l)을 계산해야 한다. 따라서, $ret.ans = left.ans + right.ans - \frac{left.rsz(left.rsz+1)}{2} - \frac{right.lsz(right.lsz+1)}{2} + \frac{(left.rsz+right.lsz)(left.rsz+right.lsz+1)}{2}$이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;362&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NdZyF/btrehBUiSC9/UMmZJLiVzF4NMZkrxGNd3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NdZyF/btrehBUiSC9/UMmZJLiVzF4NMZkrxGNd3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NdZyF/btrehBUiSC9/UMmZJLiVzF4NMZkrxGNd3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNdZyF%2FbtrehBUiSC9%2FUMmZJLiVzF4NMZkrxGNd3K%2Fimg.png&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;362&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 여기서 주의해야 할 것은, 서브노드 전체가 하나의 subarray로 존재하는 경우에는 ret.lsz 또는 ret.rsz를 다시 계산해야 한다. 예를 들어 위 그림처럼 $left.lsz = left.sz$인 경우, ret.lsz는 left.lsz가 아니라 left.sz + right.lsz이다. 마찬가지로 $right.lsz = right.sz$인 경우, $ret.rsz = left.rsz + right.sz$이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 방식으로 두 서브노드를 합칠 수 있다. 세그먼트 트리를 정의했다면 나머지는 각 쿼리에 맞게 트리에 update 또는 query를 하면 된다.&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/43</guid>
      <comments>https://kimhwon.tistory.com/43#entry43comment</comments>
      <pubDate>Tue, 7 Sep 2021 13:26:27 +0900</pubDate>
    </item>
    <item>
      <title>2021 ICPC Sinchon Summer Algorithm Camp Contest 후기</title>
      <link>https://kimhwon.tistory.com/41</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;75&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yv5U4/btrdyldXzbB/7lygJQP7TPbhl4dcW3E9oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yv5U4/btrdyldXzbB/7lygJQP7TPbhl4dcW3E9oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yv5U4/btrdyldXzbB/7lygJQP7TPbhl4dcW3E9oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyv5U4%2FbtrdyldXzbB%2F7lygJQP7TPbhl4dcW3E9oK%2Fimg.png&quot; data-origin-width=&quot;1900&quot; data-origin-height=&quot;75&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5등까지 상품이 나가는데, 시작하고서 가벼운 마음으로 대충 문제 훑어보다가 5~10분 정도 날렸다. 만약에 바로 A번 잡고 풀었다면 3솔도 할 수 있었는데 아쉬웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A. permutation making (00:14)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대한 누적합이 같게 만들어줘야 한다. 누적합을 N으로 나머지 연산을 하므로, N의 배수들은 모두 똑같이 0으로 취급된다. 따라서 누적합이 N의 배수가 나오도록 N, 1, N-1, 2, N-2, ... 이렇게 배치해주면 된다. 그러면 홀수 번째 원소들은 모두 같고, 짝수 번째 원소들은 다 다르므로 조건을 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;D. 신촌 수열과 쿼리 (01:16)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번 쿼리를 살펴보면, 구간 [l, i]에서 모든 원소가 j 이상이 되도록 l을 최대한 감소시키고, 구간 [i, r]에서 모든 원소가 j 이상이 되도록 r을 최대한 증가시키면 된다. 최솟값 세그트리를 사용해서 구간 [l, i] 또는 구간 [i, r]에 j보다 작은 원소가 있는지 O(logN) 안에 찾을 수 있다. 이분 탐색을 한 번씩 사용해서 조건을 만족하는 동안 l의 최솟값 그리고 r의 최댓값을 각각 구할 수 있다. 이렇게 하여 O(log log N) 안에 2번 쿼리를 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 쿼리는 그냥 세그트리에 update해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 잘못 읽어서 굉장히 헤멨다. 2번 쿼리의 구간에 i가 포함되어야 한다는 조건을 놓쳐서 머지소트트리+금광세그를 짜야 하나 고민했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;G. 신촌방위본부 (업솔빙)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나무가 불에 타는 조건은, 내분점 공식과 동일하다. 즉, 미사일이 떨어진 좌표를 이어서 만든 도형의 내부(모서리에 걸친 점도 포함)에 있는 모든 나무가 불에 탄다는 뜻이다. 미사일이 떨어진 좌표들의 볼록껍질을 구하고 볼록다각형의 넓이를 구한다. 볼록다각형이 격자점 위에 있으므로 &lt;i&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%ED%94%BD%EC%9D%98_%EC%A0%95%EB%A6%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;픽의 정리&lt;/a&gt;&lt;/i&gt;를 이용하면 다각형 내부에 있는 점의 개수를 구할 수 있다. 여기서 볼록다각형의 내부에 있는 보호막의 개수만큼 빼면 답이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미사일의 수가 2개 이하인 경우는 볼록다각형이 만들어지지 않으므로 예외처리를 해줘야하는데, 다 짜고 이 예외처리 부분을 짜다가 대회가 끝났다. 딱 3분만 더 있었다면 맞을 수 있었는데 매우 아쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/대회</category>
      <category>ICPCSinchon</category>
      <category>후기</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/41</guid>
      <comments>https://kimhwon.tistory.com/41#entry41comment</comments>
      <pubDate>Mon, 30 Aug 2021 21:58:23 +0900</pubDate>
    </item>
    <item>
      <title>Orange Cup 후기</title>
      <link>https://kimhwon.tistory.com/40</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1729&quot; data-origin-height=&quot;164&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFD3rg/btrdxnoU30C/bEvA9gLzZNAoMRMAlltdck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFD3rg/btrdxnoU30C/bEvA9gLzZNAoMRMAlltdck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFD3rg/btrdxnoU30C/bEvA9gLzZNAoMRMAlltdck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFD3rg%2FbtrdxnoU30C%2FbEvA9gLzZNAoMRMAlltdck%2Fimg.png&quot; data-origin-width=&quot;1729&quot; data-origin-height=&quot;164&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자다 일어났더니 대회가 2시간 가량 밖에 남지 않았다. solved.ac 뱃지 기준인 100점만 넘기자는 마인드로 대충 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;C. ko_orange (02:45)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[2100, 2400) 구간 내에서 이분 탐색을 하는데, 쿼리의 답이 잘못 주어질 수 있다. 그냥 같은 쿼리를 두 번씩 물어봐서 첫 번째 서브태스크만 해결했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A. 오렌지컵 출제하기 (03:02)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 준비 시간으로 정렬하고 작은 것부터 그리디하게 골라 나갔다. 고르면서 어떤 출제자가 L개 이상의 문제를 내야 한다면 그 문제를 뛰어 넘는다. 이렇게 하여 세 번째 서브태스크까지 해결했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제를 풀고 총 점수가 88점이었기에 100점만 만들자는 생각으로 모든 문제를 한 번 훑어보면서 찍먹했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;D. 오렌지 섬 여행하기 (04:14)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 서브태스크를 해결하기 위해 직접 $n=7$까지 손으로 그려 보니, 왠지 모든 n에 대하여 오렌지를 다 먹을 수 있을 것 같았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 $n=i$일 때 오렌지를 전부 먹을 수 있는 경로가 있다고 하면, $n=i+1$일 때 인접한 두 정점 사이에 $i+1$을 잘 끼워 넣으면 된다. $i+1$이 두 정점과 서로소일 때 끼워 넣을 수 있다. 또는 맨 앞이나 맨 뒤에는 인접한 한 정점과 서로소이기만 해도 된다. 이런 조건을 만족하면서 N까지 그리디하게 끼워 넣다 보면 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시 몰라서 assert를 넣은 채 제출했는데 한 번에 맞았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;I. 오렌지&amp;nbsp;키우기 (04:16)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$K=0$이라면 심는 즉시 오렌지를 수확할 수 있고, 이는 오렌지를 심을 수 있는 지점에 방문하고 돌아오는 데 걸리는 시간과 같다. 따라서 오렌지를 심을 수 있는 지점 중 가장 먼 곳의 거리를 답이다. 이렇게 하면 첫 번째 서브태스크를 해결할 수 있다.&lt;/p&gt;</description>
      <category>알고리즘/대회</category>
      <category>OrangeCup</category>
      <category>후기</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/40</guid>
      <comments>https://kimhwon.tistory.com/40#entry40comment</comments>
      <pubDate>Mon, 30 Aug 2021 21:32:02 +0900</pubDate>
    </item>
    <item>
      <title>Harbour.Space Scholarship Contest 2021-2022 (open for everyone, rated, Div. 1 + Div. 2)</title>
      <link>https://kimhwon.tistory.com/39</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;142&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2YoXZ/btrc9dGcUIT/UyAbjfhAKKMKK7xjvU4DDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2YoXZ/btrc9dGcUIT/UyAbjfhAKKMKK7xjvU4DDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2YoXZ/btrc9dGcUIT/UyAbjfhAKKMKK7xjvU4DDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2YoXZ%2Fbtrc9dGcUIT%2FUyAbjfhAKKMKK7xjvU4DDk%2Fimg.png&quot; data-origin-width=&quot;1175&quot; data-origin-height=&quot;142&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대박났다. carrot에서 퍼플 퍼포먼스 찍힘&amp;nbsp;:blobhappy:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;A. Digits Sum&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;interesting하지 않은 수는 맨 마지막 자리가 9인 수이다. 따라서 $\frac{(n+1)}{10}$이 답이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;B. Reverse String&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;첫 번째로 주어진 문자열을 적절히 '접어서' 두 번째 문자열로 만들 수 있는지 확인하는 문제이다. 문자열의 길이가 500 이하로 매우 작으므로, '접는' 중심을 하나씩 잡아보면서 확인해볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;C. Penalty&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;페널티킥을 10번 할 때, 최대한 빨리 승패가 결정나는 횟수를 찾는 문제이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;가능한 빨리 승패가 나는 경우로 첫 번째 팀이 최대한 많이 넣고 두 번째 팀이 최대한 적게 넣도록 ?를 채운 경우와, 첫 번째 팀이 최대한 적게 넣고 두 번째 팀이 최대한 많이 넣도록 ?를 채운 경우 두 가지를 확인해보면 된다. 각 경우에 대하여 남은 기회가 점수차보다 작아지면 승패가 결정난다. s의 길이가 10이므로 직접 시뮬레이션하면서 알아낼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;D. Backspace&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 키 대신 backspace를 누른다면 그 키에 해당하는 알파벳 하나가 사라지고, 그 알파벳의 바로 앞의 문자가 지워진다. 즉, 연속한 2개의 문자를 지워서 주어진 문자열로 만들 수 있는지 확인하면 된다. 앞에서부터 순회하면서 그리디하게 진행하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/39</guid>
      <comments>https://kimhwon.tistory.com/39#entry39comment</comments>
      <pubDate>Mon, 30 Aug 2021 21:04:28 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #732 (Div. 2)</title>
      <link>https://kimhwon.tistory.com/38</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1173&quot; data-origin-height=&quot;104&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dSvagx/btrc9ed2I25/nEa0C1cg9RbEfn72eDKQPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dSvagx/btrc9ed2I25/nEa0C1cg9RbEfn72eDKQPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSvagx/btrc9ed2I25/nEa0C1cg9RbEfn72eDKQPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSvagx%2Fbtrc9ed2I25%2FnEa0C1cg9RbEfn72eDKQPk%2Fimg.png&quot; data-origin-width=&quot;1173&quot; data-origin-height=&quot;104&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A번이 약간 말려서 당황했는데, 그래도 B, C가 잘 풀려서 다행이었다. 4솔도 노려볼 만했는데 더 풀지는 못해서 아쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;A. AquaMoon and Two Arrays&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;두 수열이 주어지고 한 수열에 적절히 연산을 하여 두 수열이 같게 만들어야 한다. 일단, 연산을 해도 각 수열의 합은 보존되므로 두 수열의 합이 다르다면 무조건 불가능하다. 두 수열의 각 원소의 차를 구하고, 그 차가 0 초과인 원소를 0 미만인 원소에 옮겨주면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;B. AquaMoon and Stolen String&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222;&quot;&gt;n개의 문자열에서 한 개의 문자열을 없앤 뒤 남은 n-1개의 문자열을 섞는다. 이 때 없어진 문자열을 찾는 문제이다.&lt;/span&gt;&lt;span style=&quot;color: #222222;&quot;&gt;n-1개의 문자열을 섞을 때 같은 열의 두 원소 즉, 문자열 S와 T가 있다면$S_i$ 와 $T_i$를 바꾼다. 따라서 각 열에 대하여 알파벳의 등장 횟수는 보존된다. 초기상태인 n개의 문자열에 대하여 각 열에 등장하는 알파벳의 수를 계산해두고, 섞인 n-1개의 문자열이 주어졌을 때, 각 열에 해당하는 알파벳의 수를 계산하면 사라진 알파벳 한 개를 찾을 수 있다.&lt;/span&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;인터랙티브&lt;/span&gt;&amp;nbsp;문제인데 왜 인터랙티브인지 모르겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;C. AquaMoon and Strange Sort&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;버블정렬의 특성을 활용한 문제이다. 주어진 수열이 정렬되었을 때, 모든 원소가 처음 위치에서 이동한 거리가 짝수가 되어야 한다. 같은 수가 등장할 수 있기 때문에 이들을 적절히 재배치하는 것이 관건이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;map을 사용하여 짝수 번째 위치에 나타나는 수와 홀수 번째 위치에 나타나는 수를 각각 센다. 정렬 한 후에 다시 &lt;span style=&quot;color: #222222;&quot;&gt;짝수 번째 위치에 나타나는 수와 홀수 번째 위치에 나타나는 수를 센다. 두 상태에서 센 수가 같다면 ok이다. 이는 짝수 번째 위치에서 다시 짝수 번째 위치로 이동하고, 홀수 번째 위치에서 다시 홀수 번째 위치로 이동했기 때문에 조건을 만족한다. 반대로 두 상태에서 센 수가 다르다면 짝수 번째 위치에서 홀수 번째 위치로 이동하거나, 홀수 번째 위치에서 짝수 번째 위치로 이동한 수가 있다는 뜻이므로 불가능한 경우이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/38</guid>
      <comments>https://kimhwon.tistory.com/38#entry38comment</comments>
      <pubDate>Wed, 25 Aug 2021 11:46:14 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #730 (Div. 2)</title>
      <link>https://kimhwon.tistory.com/37</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1173&quot; data-origin-height=&quot;103&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C5mmF/btrdcRo5RjD/otlwialVRKhVepoMZBcjP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C5mmF/btrdcRo5RjD/otlwialVRKhVepoMZBcjP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C5mmF/btrdcRo5RjD/otlwialVRKhVepoMZBcjP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC5mmF%2FbtrdcRo5RjD%2FotlwialVRKhVepoMZBcjP0%2Fimg.png&quot; data-origin-width=&quot;1173&quot; data-origin-height=&quot;103&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨디션이 다시 올라왔고 잘 풀어서 기분이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;A. Exciting Bets&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;두 음이 아닌 정수 a, b가 주어졌을 때 적절한 연산을 하여 gcd(a, b)를 최대로 하는 문제이다. 먼저, 문제에 제시된 대로 0, 0이라면 INF라고 하니 $a = b$인 경우는 0, 0으로 만들면 될 것이다. $a \ne b$인 경우, $gcd(|a-b|, 0)$ 인 상태가 최대이다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;이는 $gcd(a, b) = gcd(a-b, b)$임을 통해 확인할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #222222;&quot;&gt;라운드 중에는 위의 등식이 생각나지 않아서 직접 예제를 만들어보다 보니 우연찮게 발견했다. 맞았으니 다행이긴 한데 많이 아쉬웠던 풀이.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;B. Customising the Track&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;수열이 주어졌을 때 $\sum_{i=1}^n \sum_{j=i+1}^n | a_i - a_j |$이 최소가 되도록 적절히 연산을 하는 문제이다. 연산을 했을 때 수열의 원소의 합은 보존되기 때문에, 수열의 원소들에 최대한 균등하게 분배할 때가 최선이다. 따라서 n-reminder개의 sum/n과, reminder개의 &lt;span style=&quot;color: #222222;&quot;&gt;sum/n+1가 구성된다.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;C. Need for Pink Slips&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222;&quot;&gt;$0.1 \leq v$이므로 c, m, p에 대하여 각각 최대 10번씩 밖에 선택되지 않는다. 따라서 완전탐색으로 모든 경우를 확인해볼 수 있다. 풀이 자체는 매우 쉬운데, 실수오차를 잘 핸들링하는 것을 의도한 문제 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;D1. RPD and Rap Sheet (Easy Version)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;Easy version의 k=2 조건에서는 bitwise XOR과 동일하다. 1부터 n-1까지 모두 한 번씩 시도해 볼 수 있다. xor은 교환법칙과 결합법칙이 성립하므로, 이전에 시도해 본 값을 모두 xor해서 들고 다니다가 현재 시도할 값과 xor해서 시도하면 된다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/37</guid>
      <comments>https://kimhwon.tistory.com/37#entry37comment</comments>
      <pubDate>Wed, 25 Aug 2021 10:47:24 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #729 (Div. 2)</title>
      <link>https://kimhwon.tistory.com/35</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;144&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CgysF/btq85fhUpvr/JPut2bHRN32M38AsgpJLlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CgysF/btq85fhUpvr/JPut2bHRN32M38AsgpJLlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CgysF/btq85fhUpvr/JPut2bHRN32M38AsgpJLlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCgysF%2Fbtq85fhUpvr%2FJPut2bHRN32M38AsgpJLlK%2Fimg.png&quot; data-origin-width=&quot;1369&quot; data-origin-height=&quot;144&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바닥을 모르고 떨어지고 있다. 사실 이전 포스트 사이에 참여한 라운드가 좀 있지만 엄청나게 망하고 멘탈이 다 갈려버려서 후기도 못썼다. 정신 좀 차려보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;A. Odd Set&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;길이가 2n인 수열에서 적절히 원소를 둘씩 짝지어 각 쌍들이 모두 홀수가 되도록 할 수 있는지 확인하는 문제. 두 자연수의 합이 홀수가 되려면, 홀수+짝수 형태야 한다. 따라서 수열 내에서 홀수의 개수와 짝수의 개수를 세서 같으면 Yes 다르면 No이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;B. Plus and Multiply (업솔빙)&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;첫 번째 연산인 x * a는, 두 번째 연산 x + b로 치환될 수 있다. b = x*k (k는 자연수) 이라면 a = k+1인 x * a 연산과 동일하다. 따라서 첫 번째 연산을 적당히 하고 n까지 두 번째 연산을 적용하면 된다. 여기서 첫 번째 연산을 할 때마다 x가 a씩 증가하므로, 최대 log_a(n) 번 연산한다. 두 번째 연산도 모듈러를 통해 O(1)에 가능하다. 최종적으로 O(log n)에 가능하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;첫 번째 연산과 두 번째 연산이 서로 치환될 수 있지 않을까 하는 경험에 근거한 의심을 금방 떠올렸지만 예시 입력을 잘못 계산하면서 모든게 꼬여버렸다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;C. Strange Function (업솔빙)&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;&lt;span style=&quot;color: #222222;&quot;&gt;f(x)의 값을 고정하고 x가 어떤 수여야 하는지 관찰해보면 다음과 같은 규칙을 찾을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어떤 x가 f(x) = 2이려면, 1의 배수이면서 2의 배수가 아니어야 한다. 즉, x | lcm(1) 이다.&lt;/li&gt;
&lt;li&gt;어떤 x가 f(x) = 3이려면, 1의 배수이면서 2의 배수이면서 3의 배수가 아니어야 한다. 즉, x | lcm(1, 2) 이다.&lt;/li&gt;
&lt;li&gt;어떤 x가 f(x) = 4이려면, 1의 배수이면서 2의 배수이면서 3의 배수이면서 4의 배수가 아니어야 한다. 즉, x | lcm(1, 2, 3) 이다.&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;li&gt;어떤 x가 f(x) = k이려면, 1의 배수이면서 ... k-1의 배수이면서 k의 배수가 아니어야 한다. 즉, x | lcm(1, 2, ... , k-1) 이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 n 이하의 수 중 f(x) = k인 수의 개수는 &amp;lfloor; n / lcm(1, ... , k-1) &amp;rfloor; 개이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한편, lcm(1, 2, ... , 37) &amp;gt;&amp;nbsp;1e16 이다. 따라서 37까지만 확인하면 된다.&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/35</guid>
      <comments>https://kimhwon.tistory.com/35#entry35comment</comments>
      <pubDate>Thu, 8 Jul 2021 14:00:52 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #726 (Div. 2)</title>
      <link>https://kimhwon.tistory.com/34</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;106&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q1M9o/btq7WvEQkxr/gAXBj3toNmKd4qOvn7zM5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q1M9o/btq7WvEQkxr/gAXBj3toNmKd4qOvn7zM5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q1M9o/btq7WvEQkxr/gAXBj3toNmKd4qOvn7zM5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq1M9o%2Fbtq7WvEQkxr%2FgAXBj3toNmKd4qOvn7zM5K%2Fimg.png&quot; data-origin-width=&quot;1168&quot; data-origin-height=&quot;106&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;종강 후 오랜만에 버추얼을 돌았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A. &lt;span style=&quot;color: #222222;&quot;&gt;Arithmetic Array&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;주어진 수열의 길이를 n, 합을 x라 하고, 새로 추가한 수들의 개수를 m, 그 합을 k라고 하면 아래와 같은 식으로 표현할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;395&quot; width=&quot;201&quot; height=&quot;151&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tUHhd/btq7SL3GgZV/QkNGvdCi2px2Pgh7KF2pj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tUHhd/btq7SL3GgZV/QkNGvdCi2px2Pgh7KF2pj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tUHhd/btq7SL3GgZV/QkNGvdCi2px2Pgh7KF2pj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtUHhd%2Fbtq7SL3GgZV%2FQkNGvdCi2px2Pgh7KF2pj0%2Fimg.png&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;395&quot; width=&quot;201&quot; height=&quot;151&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x - n이 0 이하이면, m=1로 하고 k가 x-n-m이면 성립한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;x - n이 0 초과이면, k=0로 하고 (즉, 새로 추가할 모든 원소를 0으로 하고) m을 x-n이면 성립한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 x - n이 0 이하일 때 1개, 0 초과일 때, x-n개 추가하면 항상 성립한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;B. &lt;span style=&quot;color: #222222;&quot;&gt;Bad Boy&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;이동 거리는 맨하탄 거리라고 할 수 있다. 따라서 경로와 무관하게 이동 거리는 가장 먼 두 점이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1274&quot; data-origin-height=&quot;321&quot; data-filename=&quot;blob&quot; width=&quot;657&quot; height=&quot;165&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvd5mg/btq7SMhgOc4/F50HuedcTVwDkG56PVH6H0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvd5mg/btq7SMhgOc4/F50HuedcTVwDkG56PVH6H0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvd5mg/btq7SMhgOc4/F50HuedcTVwDkG56PVH6H0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcvd5mg%2Fbtq7SMhgOc4%2FF50HuedcTVwDkG56PVH6H0%2Fimg.png&quot; data-origin-width=&quot;1274&quot; data-origin-height=&quot;321&quot; data-filename=&quot;blob&quot; width=&quot;657&quot; height=&quot;165&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림에서처럼 (0, 0)과 (N, M)으로 하면 이동 거리를 최대로 할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;C. &lt;span style=&quot;color: #222222;&quot;&gt;Challenging Cliffs&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;일단 주어진 수열 h을 정렬한다. &lt;span style=&quot;color: #222222;&quot;&gt;첫 번째 조건인 |h_1 - h_n|이 최소가 되도록 하기 위해서, 수열을 순회하면서 인접한 원소끼리 차이가 가장 작은 원소 둘을 선택한다. 선택한 원소의 위치를 a, b라고 해보자.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;두 번째로 h_&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;i &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;le; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;h_{&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;1}인 위치가 최대한 많게 배치해보자. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;h_j, h_{j+1}, ... , h_n,&amp;nbsp; &amp;nbsp;h_1, h_2, ... , h_i 순서로 한다면 h_n과 h_1 한 번을 제외한 나머지 모든 경우가 조건을 만족하므로 최대이다. 여기서&lt;/span&gt;&lt;span style=&quot;color: #222222;&quot;&gt; 만약 길이가 2일 경우에는 h_j &amp;gt; h_i 일 수 있다. 이러한 경우도 고려해보면 &lt;span style=&quot;color: #222222;&quot;&gt;h_i, h_{j+1}, ... , h_n,&amp;nbsp; &amp;nbsp;h_1, h_2, ... , h_j 순서로 배치할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;D. &lt;span style=&quot;color: #222222;&quot;&gt;Deleting Divisors (업솔빙)&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;&lt;span style=&quot;color: #222222;&quot;&gt;아직도 게임 쪽은 전혀 감이 없다. 해설을 보았으나 그만 정신이 혼미해졌다. dp로 100까지 돌려본 뒤, 규칙을 발견하였다. dp식은 다음과 같다. x의&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #222222;&quot;&gt; 약수 중, k != 0, k != x인 k에 대하여, dp[x][a] = !(dp[x - k_1][!a] &amp;amp;&amp;amp; dp[x - k_2][!a] &lt;span style=&quot;color: #222222;&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; ... &lt;span style=&quot;color: #222222;&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&amp;nbsp;dp[x - k_n][!a])&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n이 2의 홀수 제곱일 경우는 무조건 Bob이 승리, 그 외의 경우에는 홀수엔 Bob, 짝수엔 Alice가 승리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;E1. Erase and Extend (Easy Version)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사전 순 비교이므로 앞쪽의 문자가 무조건 우선이다. 따라서 두 번째 연산으로 복사해 나가기 전에, 일단 적절히 잘라내서 최적의 prefix를 만들어야 할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길이가 1부터 n인 prefix를 만들고 복사해서 n개의 문자열들을 만든다. 입력이 충분히 작으므로, 이 문자열들을 전부 비교해보고 가장 작은 문자열을 찾아도 된다.&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/34</guid>
      <comments>https://kimhwon.tistory.com/34#entry34comment</comments>
      <pubDate>Tue, 22 Jun 2021 23:30:41 +0900</pubDate>
    </item>
    <item>
      <title>MFC Serialization ― Expression: _CrtisValidHeapPointer(block)</title>
      <link>https://kimhwon.tistory.com/33</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;MFC template collection(CArray, CList 등)을 직렬화 할때, Serialize메서드를 호출해서 사용하면 _CrtisVaildHeapPointer(block) 메세지와 함께 exception이 발생하는 것을 경험할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 에러 메세지를 이해해보면 일반적으로 동적할당을 해제 할 때 발생하는데, 잘못된 위치를 가리키는 포인터를 해제하려고 할 때 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 Serialize메서드에서 collection의 각 원소를 복사할 때, 포인터 단위로 단순 대입을 하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시로 CList의 Serialize 구현부를 따라가보면 원소를 복사할 때 SerializeElements를 사용하는 것을 알 수 있다. 해당 함수의 구현부는 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1621854993583&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;template&amp;lt;class TYPE&amp;gt;
void AFXAPI SerializeElements(CArchive&amp;amp; ar, TYPE* pElements, INT_PTR nCount)
{
	ENSURE(nCount == 0 || pElements != NULL);
	ASSERT(nCount == 0 ||
		AfxIsValidAddress(pElements, (size_t)nCount * sizeof(TYPE)));

	// default is bit-wise read/write
	if (ar.IsStoring())
	{
		TYPE* pData;
		UINT_PTR nElementsLeft;

		nElementsLeft = nCount;
		pData = pElements;
		while( nElementsLeft &amp;gt; 0 )
		{
			UINT nElementsToWrite;

			nElementsToWrite = UINT(__min(nElementsLeft, INT_MAX/sizeof(TYPE)));
			ar.Write(pData, nElementsToWrite*sizeof(TYPE));
			nElementsLeft -= nElementsToWrite;
			pData += nElementsToWrite;
		}
	}
	else
	{
		TYPE* pData;
		UINT_PTR nElementsLeft;

		nElementsLeft = nCount;
		pData = pElements;
		while( nElementsLeft &amp;gt; 0 )
		{
			UINT nElementsToRead;

			nElementsToRead = UINT(__min(nElementsLeft, INT_MAX/sizeof(TYPE)));
			ar.EnsureRead(pData, nElementsToRead*sizeof(TYPE));
			nElementsLeft -= nElementsToRead;
			pData += nElementsToRead;
		}
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pElements로 받아온 원소의 포인터를 그대로 pData에 복사한 뒤, 여기에 Write 또는 EnsureRead로 bit-wise read/write를 하고 있다. 만약 원소가 기본 데이터 타입(int, TCHAR 등)이면 큰 문제 없이 동작하겠지만 class라면, 특히 멤버로 또다른 class나 collection을 가지고 있다면 이와 같은 문제가 생길 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원소의 멤버로 있는 값이 포인터를 가지고 있다면, 이 포인터 값도 함께 직렬화된다. 불러오기를 통해 가져온 포인터 값은, 현재 runtime 중인 프로세스가 가지고 있는 heap이 아니라, 이전에 저장했던 프로세스가 가지고 있는 heap을 가리키고 있는 포인터일 것이다. 따라서 잘못된 위치를 가리키는 포인터를 사용하여 _CrtisValidHeapPointer exception이 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해서는 다음과 같이 SerializeElements를 오버로딩하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1621856037537&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;template&amp;lt;&amp;gt;
void AFXAPI SerializeElements(CArchive&amp;amp; ar, MyClass* pElements, INT_PTR nCount)
{
	// Do what you want.
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 그냥 Serialize메서드를 호출하지 말고, 반복문 등을 사용해서 모든 원소를 직접 ar 객체에 &amp;lt;&amp;lt; 또는 &amp;gt;&amp;gt;연산자로 써 주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 자료&lt;/p&gt;&lt;br&gt;
&lt;a href=&quot;https://docs.microsoft.com/ko-kr/cpp/mfc/reference/collection-class-helpers?view=msvc-160#serializeelements&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.microsoft.com/ko-kr/cpp/mfc/reference/collection-class-helpers?view=msvc-160#serializeelements&quot;&gt;https://docs.microsoft.com/ko-kr/cpp/mfc/reference/collection-class-helpers?view=msvc-160#serializeelements
&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://docs.microsoft.com/ko-kr/cpp/mfc/how-to-make-a-type-safe-collection?view=msvc-160#_core_implementing_helper_functions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.microsoft.com/ko-kr/cpp/mfc/how-to-make-a-type-safe-collection?view=msvc-160#_core_implementing_helper_functions&quot;&gt;https://docs.microsoft.com/ko-kr/cpp/mfc/how-to-make-a-type-safe-collection?view=msvc-160#_core_implementing_helper_functions
&lt;/a&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CArray</category>
      <category>Collection</category>
      <category>mfc</category>
      <category>_CrtisValidHeapPointer</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/33</guid>
      <comments>https://kimhwon.tistory.com/33#entry33comment</comments>
      <pubDate>Mon, 31 May 2021 21:40:03 +0900</pubDate>
    </item>
    <item>
      <title>HI-ARC PS톤 후기</title>
      <link>https://kimhwon.tistory.com/32</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;학회에서 주말 동안 문제 풀면 상 받는 대회를 연다고 해서 호다닥 참가했다. 결과는 예상대로 1등.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구체적인 공지나 홍보가 없어서 그런지 다들 별로 참여 안해서 노잼이 돼버렸다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1275&quot; data-origin-height=&quot;168&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5wLeW/btq4YNpqzfI/nOKdfU8cjmY8aRgDXqcLO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5wLeW/btq4YNpqzfI/nOKdfU8cjmY8aRgDXqcLO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5wLeW/btq4YNpqzfI/nOKdfU8cjmY8aRgDXqcLO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5wLeW%2Fbtq4YNpqzfI%2FnOKdfU8cjmY8aRgDXqcLO0%2Fimg.png&quot; data-origin-width=&quot;1275&quot; data-origin-height=&quot;168&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이하는 간단한 풀이이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A. 희원이의 뉴욕 생활&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2524&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2524&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쓸데없이 지문이 길다. 맨하탄 거리와 유클리드 거리를 알면 간단한 문제.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-origin-width=&quot;364&quot; data-origin-height=&quot;257&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpzzRm/btq453dv8lb/vraBmRmQUbOH0UnEnxA5xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpzzRm/btq453dv8lb/vraBmRmQUbOH0UnEnxA5xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpzzRm/btq453dv8lb/vraBmRmQUbOH0UnEnxA5xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpzzRm%2Fbtq453dv8lb%2FvraBmRmQUbOH0UnEnxA5xk%2Fimg.png&quot; data-origin-width=&quot;364&quot; data-origin-height=&quot;257&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림에서 검은 점은 점 A와 B를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A와 B 사이 점선이 맨하탄 거리로 최단 거리임이 자명하다. 이때, 대각선이 적절히 있다면 빨간 점선 대신 빨간 실선을 타고 이동할 수 있다. 따라서 (전체 점선 길이) - (빨간 점선 길이) +(빨간 실선 길이) 가 답이다.&lt;br /&gt;대각선을 활용할 수 없는 경우는 (1) A와 B로 이루어진 직사각형(초록)을 지나지 않는 경우와 (2) 대각선의 기울기와 진행 방향이 엇갈리는 경우이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번은 대각선을 나타내는 방정식에 x, y를 적절히 대입해서 확인해보면 되고, 2번은 A―B의 위치 관계와 기울기를 비교해보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;허용 오차가 1e-9라 무서워서 long double 썼는데 끝나고 다시 내보니 double 써도 맞았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;B. 킥&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/11566&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/11566&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;m이 작다. gap, offset에 대하여 이중 반복문으로 완전 탐색을 돌려버리면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;C. 성냥&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2029&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2029&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 격자를 잘 파싱한 뒤, &lt;span style=&quot;color: #555555;&quot;&gt;24개의 성냥을 다 확인해보면 된다. (row % 3 == 0 &amp;amp;&amp;amp; col % 3 == 1) 이면 가로로 놓인 성냥, (row % 3 == 1 &amp;amp;&amp;amp; col % 3 == 0) 이면 세로로 놓인 성냥을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;D. 신나는 분수 계산&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/9215&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/9215&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #555555;&quot;&gt;pair&amp;lt;ll, ll&amp;gt; 등으로 분수를 관리해주면 된다. 나는 구조체로 만들어서 operator overloading을 했다. 입력이 분수 상태로 주어지므로, string으로 받고 콤마와 나눗셈기호를 토큰으로 파싱하자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;E. 무제&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/9548&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/9548&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #555555;&quot;&gt;문제 설명부터가 단순하다. 생각할 것도 없는 그냥 &lt;span style=&quot;color: #555555;&quot;&gt;string&lt;/span&gt; 사용법 연습 문제&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;F. 망가진&amp;nbsp;키보드&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/6503&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/6503&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #555555;&quot;&gt;문자열 s에서 i부터 시작하는 m개의 서로 다른 글자를 가진 부분 문자열과 i+1부터 시작하는 &lt;span style=&quot;color: #555555;&quot;&gt;m개의 서로 다른 글자를 가진 부분 문자열은 s_i를 제외하고 prefix가 겹친다. 따라서 이 부분을 window로 잡고 투포인터로 해결이 가능하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;m개의&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 서로 다른 글자를 가진 문자열을 구간으로 잡고 투포인터를 돌리면 된다. 이때 가장 긴 구간의 길이가 답.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;G. 대운하&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2350&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2350&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #555555;&quot;&gt;Minimum spanning tree가 아니라 Maximum spanning tree를 구한다고 생각해보자. &lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;가중치가 큰 순서대로 간선을 하나씩 그래프에 추가해보고, 추가한 간선에 의해 연결되는 경로가 있는지 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;간선의&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 개수가 최대 &lt;span style=&quot;color: #555555;&quot;&gt;1e5이므로 그대로 구현하면 당연히 TLE지만, 우리가 알고 싶은 것은 가중치의 값에 대한 것이므로 가중치가 같은 간선을 그래프에 추가할 때마다 경로를 확인하지 않아도 된다. 즉, 가중치가 같은 간선들을 그룹지어 전부 추가한 뒤 한 번만 경로를 확인하면서 진행해도 괜찮다. 가중치는 최대 &lt;span style=&quot;color: #555555;&quot;&gt;200이므로 시간 내에 해결할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;H. 최종&amp;nbsp;순위&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/7775&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/7775&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;d가 1일 때와 아닐 때로 나눠서 생각해볼 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;먼저&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt; d&amp;gt;1이면, 상위 d명이 d-1, d-2, ... , 1, 0점을 나눠 가지고 남은 사람들에게 0점씩 분배해주면 최소한의 점수만 사용해서 조건을 만족할 수 있다. &lt;span style=&quot;color: #555555;&quot;&gt;남은 p점은 1등에게 몰아줘버리자. &lt;/span&gt;만약 이렇게 나눠주었는데도 p가 부족해지면 불가능한 경우이다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;d=1이면,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 상위 k명이 같은 점수를 나눠 가져가야 한다. 이 k명에게 최대한 많은 점수를 분배해주면 각각 p/k점씩 분배될 것이다. 그리고 남은 n-k명의 사람들은 p%k점을 나눠 가져 간다. n-k=0인데 (나눠줄 사람이 더 없는데) &lt;span style=&quot;color: #555555;&quot;&gt;p%k점이 남거나, p%k점을 n-k명에게 나눠주었는데 ceil (p%k)/(n-k) 이 &lt;span style=&quot;color: #555555;&quot;&gt;p/k점보다 크다면(상위권보다 더 받아버린다면) 실패한다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;I. 목걸이 수열&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2070&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/2070&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt;그리디하게 가능한 긴 목걸이 수열을 찾아 나가면 된다. S_1부터 가장 긴 목걸이 수열을 그룹화하고, 남은 S_i부터 또 가장 긴 수열을 그룹화하고 ... 이런 식으로 찾아 나가면 조건에 만족한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;조건 2)&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 가능한 가장 긴 목걸이 수열이므로, 더 합쳐서 목걸이 수열을 만들 수 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;조건 1)&lt;/span&gt;&lt;span style=&quot;color: #555555;&quot;&gt; 목걸이 수열은 0*1* 꼴 또는 이들의 조합이다. 0을 기준으로 1이 어떻게 배치되어 있는지 생각해보자. 수열을 잘 회전해서 목걸이 수열이 작아지려면, prefix에 얼마나 많은 0이 배치될 수 있는지, 그리고 남은 부분에 1이 얼마나 적게 배치될 수 있는지에 달렸다. 조건1을 만족하지 않는 경우를 예를 들면, (011)(01111) 이런 형태가 있을 것이다. 즉, 앞쪽 수열이 뒤쪽 수열보다 작으면, 그 두 수열을 합쳐도 목걸이 수열이다. 따라서 조건2처럼 더 합쳐서 목걸이 수열을 선택한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;J. 동전&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/3363&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/3363&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #555555;&quot;&gt;12개의 동전을 {0, 0, ... , 1, ... , 0} 이렇게 대입하여 더 무거운 동전 하나를 만들어보고, 반대로 &lt;span style=&quot;color: #555555;&quot;&gt;{1, 1, ... , 0, ... , 1} 이렇게 대입하여 더 가벼운 동전 하나를 만들어본 뒤, 주어진 수식에 직접 대입해서 계산해본다. 조건을 만족하는 상태가 2가지 이상이면 indefinite이고, 1가지 미만이면 impossible이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;K. 정사각형&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/3614&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/3614&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 520px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style16&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 258px;&quot;&gt;
&lt;td style=&quot;width: 412.8px; height: 258px;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;401&quot; height=&quot;254&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;486&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baEkud/btq4ZgZTLoP/gjA7OYDM644s4vMPtxqWEk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baEkud/btq4ZgZTLoP/gjA7OYDM644s4vMPtxqWEk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baEkud/btq4ZgZTLoP/gjA7OYDM644s4vMPtxqWEk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaEkud%2Fbtq4ZgZTLoP%2FgjA7OYDM644s4vMPtxqWEk%2Fimg.png&quot; width=&quot;401&quot; height=&quot;254&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;486&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 412.8px; height: 258px;&quot;&gt;&lt;span&gt;문제의 직사각형을 좌표평면으로 옮겨서 생각해보자. 가로길이 a와 세로 길이 b는 각각 x축, y축에 대응되고 대각선은 원점과 (a, b)를 잇는 선분으로 이해된다.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;서로소인 a, b에 대하여 왼쪽 그림에 표현하였다. x 증가량에 대하여, y의 증가량이 1을 넘는 순간마다 새로운 정사각형(초록)이 소모하는 것을 관찰할 수 있다. 또한 x가 a만큼 증가하면서 1을 넘는 순간마다 새로운 정사각형(노랑)을 소모하는 것을 볼 수 있다.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;따라서 이 경우, (&lt;span style=&quot;color: #555555;&quot;&gt;정사각형의 개수&lt;/span&gt;) = a + b - 1 이다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 262px;&quot;&gt;
&lt;td style=&quot;width: 412.8px; height: 262px;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;400&quot; height=&quot;259&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;488&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAzga8/btq44Qzv1yL/frIH8EnPlxmkVb5OyT52C1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAzga8/btq44Qzv1yL/frIH8EnPlxmkVb5OyT52C1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAzga8/btq44Qzv1yL/frIH8EnPlxmkVb5OyT52C1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAzga8%2Fbtq44Qzv1yL%2FfrIH8EnPlxmkVb5OyT52C1%2Fimg.png&quot; width=&quot;400&quot; height=&quot;259&quot; data-origin-width=&quot;754&quot; data-origin-height=&quot;488&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 412.8px; height: 262px;&quot;&gt;&lt;span&gt;한편, 공약수가 있는 a와 b에 대하여도 생각해보자. 마찬가지로 x 증가량에 대하여 y의 증가량이 1을 넘는 순간마다 새로운 정사각형(초록)을 소모하나, a와 b의 공약수인 시점에는 정사각형의 내부를 지나치는 것이 아니라 꼭짓점을 지나간다.(파란 점)&lt;br /&gt;&lt;br /&gt;이 때는 새로운 정사각형(초록)을 소모하지 않게 된다. 따라서 a와 b의 공약수가 나타나는 횟수만큼, 서로소인 경우보다 정사각형을 덜 소모하는 것이다.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;따라서 이 경우, (&lt;span style=&quot;color: #555555;&quot;&gt;정사각형의 개수&lt;/span&gt;) = a + b - gcd(a, b) 이다.&lt;/span&gt;&lt;br /&gt;&lt;span&gt;a와 b가 서로소라면 gcd(a, b) = 1이므로, 같은 식으로 표현할 수 있다.&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하여 문제에서 주어진 f(R)을 a와 b로 표현할 수 있게 되었다. 문제에서 구해야 할 것은 f(R) = N을 만족하는 서로 다른 R의 개수이다. 방금 만든 식을 대입해서 다시 표현해보면, a + b - gcd(a, b) = N을 만족하는 서로 다른 a, b 쌍의 개수 (단, a &amp;lt;= b)를 구하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gcd(a, b)를 g라고 하고, 양변을 g로 나눠보자. 여기서 a/g와 b/g는 서로소임을 관찰해낼 수 있다. 또한 두 정수 a/g와 b/g의 합에 정수 1을 뺀 값인 N/g 또한 정수라는 점을 관찰할 수 있다. 다시 한번 식을 정리해보면 a/g + b/g = N/g + 1 (단, a/g와 b/g는 서로소, a/g &amp;lt;= b/g)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N/g가 정수이므로, g는 N의 약수이다. N의 모든 약수에 대하여 g를 고정하고 가능한 a/g와 b/g를 전부 세주면 된다. 그러면 N의 약수 g를 구하는데 O( sqN )이고, 각 g에 대하여 합이 N/g + 1인 두 서로소를 구하는데 O( g )이므로, 정리하면 O( N )이 된다. (g &amp;lt;= sqN)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무리 생각해도 골드4의 난이도는 아닌 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;N. 도미노&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1073&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/1073&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도미노에 적힌 수를 정점, 도미노를 간선으로 하는 그래프로 모델링을 해 보면 이 문제는 그래프에서 서로 다른 오일러 회로의 개수를 세는 문제로 해석된다. 직접 다 세볼 수는 있겠지만, TLE가 날게 뻔하므로(답이 최대 2^64일 수도 있다), 잘 관찰해서 경우의 수를 계산해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오일러 회로가 성립하려면 모든 정점의 차수가 짝수여야 한다. 즉, 오일러 경로를 따라 이동한다면 어떤 정점에 들어올 때 쓸 간선 하나와 나갈 때 쓸 간선 하나가 필요하다. 정점의 차수를 d라고 하면, 이 정점을 방문하는 횟수는 d/2번이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 d/2번의 방문마다 들어올 때 쓸 간선 하나와 나갈 때 쓸 간선 하나를 골라야 한다. 이때, 오일러 경로가 아니라 오일러 회로를 구해야 하므로 오일러 경로를 역방향으로 도는 경우 즉, 들어올 때 쓸 간선으로 나가고 나갈 때 쓸 간선으로 들어오는 경우를 하나의 경우로 처리해야 한다. 따라서 첫 번째로 방문하면, 가능한 경우의 수는 dC2 이다. 두 번째로 방문하면, 이미 선택한 두 간선을 제외한 d-2C2이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 총 d/2번 방문한다. 여기서도 오일러 회로이므로 각 방문에서 선택한 간선들의 순서는 무의미하다. 따라서 (d/2)!로 나눈 (dC2 * d-2C2 * ... * 2C2) / (d/2)! 이 한 정점에서 선택할 수 있는 모든 경우의 수이다. 모든 정점에 대하여 이 경우의 수를 곱해주면 답이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;d에 따른 경우의 수를 f(d)라고 하면, f(d)는 미리 전처리로 구해 둘 수 있는데, 잘 관찰해보면 다음과 같은 규칙을 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;d = 2,&amp;nbsp; &amp;nbsp;f(d) = ( 2C2 ) / ( 1 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;d = 4,&amp;nbsp; &amp;nbsp;f(d) = ( &lt;u&gt;2C2&lt;/u&gt; * 4C2 ) / ( &lt;u&gt;1&lt;/u&gt; * 2 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;d = 6,&amp;nbsp; &amp;nbsp;f(d) = ( &lt;u&gt;2C2 * 4C2&lt;/u&gt; * 6C2 ) / ( &lt;u&gt;1 * 2&lt;/u&gt; * 3 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;d = 8,&amp;nbsp; &amp;nbsp;f(d) = ( &lt;u&gt;2C2 * 4C2 * 6C2&lt;/u&gt; * 8C2 ) / ( &lt;u&gt;1 * 2 * 3&lt;/u&gt; * 4 )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 이전 항을 활용해 f(d) = f(d-2) * ( dC2 / (d/2) )로 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;O. 팰린드롬 보행&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/12950&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/12950&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팰린드롬 문자열의 양 끝에 같은 문자를 추가하면 팰린드롬 문자열이라는 점을 활용하자. dp[i][j] = i부터 j를 잇는 가장 짧은 팰린드롬 보행의 길이라고 정의해보자. 초기에는 인접한 두 정점에 대하여 간선 하나로 이루어진 길이가 1인 보행들 그리고 정점 하나를 기준으로 연결된 두 간선으로 이루어진 길이가 2인 보행들이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 i, j에 대하여 만약 dp[i][j]가 존재한다면 i에 연결된 간선들과 j에 연결된 간선들을 함께 살펴본다. i에 연결된 i'으로 가는 간선의 문자와 j에 연결된 j'으로 가는 간선의 문자가 같다면, dp[i'][j'] = min(dp[i'][j'], dp[i][j] + 2)로 정의할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0과 1이 연결될 때까지 즉, dp[0][1]이 존재할 때까지 반복하면 된다. O( N^2 * M )에 해결 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 구현은 dp[i][j]가 존재하는 쌍 (i, j)를 큐에 넣어서 관리하였다. 이해를 돕기 위해, 예시 입력에 대한 그래프와 dp테이블을 아래 첨부한다. (사실 그려놓고 설명에 끼워 넣을 데를 모르겠어서 여기서 넣었다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2562&quot; width=&quot;557&quot; height=&quot;927&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AYfP6/btq454RUZqg/21bQw4qVBnSNnTVDnfMpqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AYfP6/btq454RUZqg/21bQw4qVBnSNnTVDnfMpqK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AYfP6/btq454RUZqg/21bQw4qVBnSNnTVDnfMpqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAYfP6%2Fbtq454RUZqg%2F21bQw4qVBnSNnTVDnfMpqK%2Fimg.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2562&quot; width=&quot;557&quot; height=&quot;927&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>알고리즘/대회</category>
      <category>후기</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/32</guid>
      <comments>https://kimhwon.tistory.com/32#entry32comment</comments>
      <pubDate>Mon, 17 May 2021 16:54:26 +0900</pubDate>
    </item>
    <item>
      <title>Contest 2050 and Codeforces Round #718 (Div. 1 + Div. 2)</title>
      <link>https://kimhwon.tistory.com/30</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1460&quot; data-origin-height=&quot;98&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/99nTy/btq3mPhNlAb/gESt47hQtgsaoxkK7LRqmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/99nTy/btq3mPhNlAb/gESt47hQtgsaoxkK7LRqmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/99nTy/btq3mPhNlAb/gESt47hQtgsaoxkK7LRqmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F99nTy%2Fbtq3mPhNlAb%2FgESt47hQtgsaoxkK7LRqmK%2Fimg.png&quot; data-origin-width=&quot;1460&quot; data-origin-height=&quot;98&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1+2라 생각보다 풀만 했다. 블루 수복 완료&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;A. Sum of 2050&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;문제에서 정의한 &lt;i&gt;2050-number&lt;/i&gt;를 잘 관찰해 보면 a * &lt;span style=&quot;color: #333333;&quot;&gt;2050*10^b + c&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;*&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2050*10^d + ... 이고 여기서 2050을 묶어내면 2050 * (a*10^b + c*10^d + ...)이다. 즉, 2050에 임의의 자연수가 곱해진 모양이므로 주어진 수를 2050으로 나눠보면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;B. Morning Jogging&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;체크포인트 사이 경로들의 최솟값을 관리해주면 된다. 일단 수열 &lt;span style=&quot;color: #333333;&quot;&gt;b_i를 정렬하자.&lt;/span&gt;&amp;nbsp;i번째 체크 포인트까지 잘 도착했다고 해보자. i+1번째 체크포인트에 가는 경로들 b_ij를 잘 배분해서 최소가 되게 만들어줘야 할 것이다. 현재까지 각 경로의 최솟값(i번째 체크포인트까지 왔을 때 각 runner의 &lt;span&gt;tiredness&lt;/span&gt;)을 t_j라고 하면, t의 각 원소들을 가능한 최소로 만드는게 최적이다. 따라서 pair(t, j)를 내림차순으로 정렬하고, 가장 큰 t_j에 b_i+1중 가장 큰 원소를 매칭해주자. 이 과정을 2차원벡터 등에 잘 저장해서 trace해주면 된다.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;C. Fillomino 2&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;주대각선에 있는 숫자만큼 계단 모양을 인접하게 색칠해야 한다. 일단 주대각선에 있는 숫자들이 permutation이고 합이 계단 모양에 있는 칸 수와 같으므로 다 칠할 수 있다고 합리적 의심을 해보자. 만약에 (i, i)에 있는 수로 (i-1, i-1)을 방해하려면 i-1줄 이상으로 올라가야 한다. 그런데&lt;span style=&quot;color: #333333;&quot;&gt; i+1줄까지 가장 많이 칠해진 경우는 N, N-1, N-2, ... 만큼 칠해진 경우일 것이며 i+1줄까지 계단 모양의 칸 수 또한 &lt;span style=&quot;color: #333333;&quot;&gt;N, N-1, N-2, ...&lt;span&gt; 으로 서로 같다. 즉, 항상 자신과 같은 줄이나 그 아래 줄만 사용해서 모두 색칠할 수 있다. 따라서 최대한 아래쪽으로 붙여서 칠해나가면 항상 색칠이 가능하다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;span&gt;D. Explorer Space (업솔빙)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;span&gt;역시나 DP가 발목을 잡는다. 1시간반이나 붙잡고 있었는데 다익스트라를 사용한 풀이로 풀다가 망했다.&lt;br /&gt;dichoy27의 풀이는 이러하다. &lt;span&gt;일단 갔다 와야되니까 K가 홀수일때는 항상 불가능하다. 그리고 &lt;span&gt;오는 길 가는 길 똑같으니까 K/2번 가는 것만 생각하면 된다. &lt;span&gt;dp[i][j][d] = (i, j)위치에서 d만큼 이동했을 때 최솟값이라 하면, &lt;span style=&quot;color: #333333;&quot;&gt;dp[i][j][d] = &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;min&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dp&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;i&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;j&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;d&lt;/span&gt;&lt;span&gt;],&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; dp&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;i&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dx&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;k&lt;/span&gt;&lt;span&gt;]][&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;j&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dy&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;k&lt;/span&gt;&lt;span&gt;]][&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;d&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; dist&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;i&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;j&lt;/span&gt;&lt;span&gt;][&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;k&lt;/span&gt;&lt;span&gt;]). 즉, 직전 위치 (&lt;span style=&quot;color: #000000;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dx&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;k&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;], &lt;span style=&quot;color: #000000;&quot;&gt;j&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dy&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;k&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;)에서 상하좌우로 이동해 온 거리 &lt;span style=&quot;color: #000000;&quot;&gt;dist&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;i&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;j&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;][&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;k&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;]를 더한 값과 현재 값 중 최솟값을 계속 관리해준다&lt;/span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/30</guid>
      <comments>https://kimhwon.tistory.com/30#entry30comment</comments>
      <pubDate>Sat, 24 Apr 2021 03:25:31 +0900</pubDate>
    </item>
    <item>
      <title>2125번: 좀</title>
      <link>https://kimhwon.tistory.com/29</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2125&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.acmicpc.net/problem/2125&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618936734047&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;2125번: 좀&quot; data-og-description=&quot;첫째 줄에 다섯 정수 N, X, Y, U, V가 주어진다. 이는 좀의 현재 위치가 (X, Y)이고, 이동하려는 곳이 (U, V)라는 의미이다. 다음 N개의 줄에는 기워진 부분들을 의미하는 볼록다각형이 주어진다. 각 줄&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/2125&quot; data-og-url=&quot;https://www.acmicpc.net/problem/2125&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bd2Qlt/hyJWtcLDxv/gLwRiYx1Bx4xKwh5kbDYSk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2125&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/2125&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bd2Qlt/hyJWtcLDxv/gLwRiYx1Bx4xKwh5kbDYSk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;2125번: 좀&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;첫째 줄에 다섯 정수 N, X, Y, U, V가 주어진다. 이는 좀의 현재 위치가 (X, Y)이고, 이동하려는 곳이 (U, V)라는 의미이다. 다음 N개의 줄에는 기워진 부분들을 의미하는 볼록다각형이 주어진다. 각 줄&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kimhwon.tistory.com/27&quot;&gt;kimhwon.tistory.com/27&lt;/a&gt;&amp;nbsp;와 매우 유사한 문제. 다만 원 대신 볼록 다각형이 등장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시점과 종점이 주어지고, 여러 개의 볼록 다각형이 주어진다. 볼록 다각형들의 내부를 지나지 않으면서 종&lt;span style=&quot;color: #000000;&quot;&gt;점에 도착하고자 할 때 최단 경로의 길이 (또는 불가능한지)를 구하면 된다. 단, 여기서 볼록 다각형의 내부란 모서리를 포함하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;위 문제에서와 같은 전략으로 모든 꼭짓점들과 시점, 종점을 잇는 선분을 모두 만든다. 만든 선분이 모든 볼록 다각형의 외부에 있다면 사용 가능한 선분이다. 사용 가능한 선분으로 이루어진 그래프에서 최단 경로를 구하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;선분이 볼록 다각형의 내부/외부에 있는지 판정이 매우 까다롭지만, 총 4가지 경우로 분류할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;선분의 끝점과 다각형의 모서리가 만나는 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;선분의 끝점과 다각형의 꼭짓점이 만나는 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;선분의 중간과 다각형의 꼭짓점이 만나는 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;선분의 중간과 다각형의 모서리가 만나는 경우&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;네 번째 경우는 선분 교차 판정으로 간단하게 구할 수 있다.(bool intersect(const Line&amp;amp; a, const Line&amp;amp; b))&amp;nbsp; 만약 교차한다면 선분이 다각형 내부에 있음이 자명하다.&lt;br /&gt;나머지 세 경우는 그림으로 정리했다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1344&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqjHvU/btq26nZUATe/PjaZlZ3DEGLvL1s1PPref1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqjHvU/btq26nZUATe/PjaZlZ3DEGLvL1s1PPref1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqjHvU/btq26nZUATe/PjaZlZ3DEGLvL1s1PPref1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqjHvU%2Fbtq26nZUATe%2FPjaZlZ3DEGLvL1s1PPref1%2Fimg.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1344&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파란 선은 확인하려는 선분, 검은 선은 다각형의 모서리, 초록과 빨간 선은 CCW 상태로 CCW면 초록색, CW면 빨간색이다. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;선분 하나에 대하여, 모든 다각형의 모든 모서리를 순회하면서 위의 4가지 조건을 다 확인하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;http://boj.kr/5e2751cb42a6468591321a8bc99f87c0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;boj.kr/5e2751cb42a6468591321a8bc99f87c0&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;논리적으로 이렇게 하면 맞아야 정상이겠지만... 예제 중에 볼록다각형이 아닌 테케가 하나 있다. 게시판에 글을 쓰긴 했으나 아직 반영되진 않았다. 직접 출처인 &lt;i&gt;&lt;a href=&quot;http://acm.ro/2005/problems.htm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;SEERC 2005&lt;/a&gt;&lt;/i&gt;에서 데이터를 받아서 확인해보니, 미세하게 안쪽으로 파고든 점이 하나 있는 다각형이 있었다. 이를 예외처리하기 위해, 선분의 중점을 잡고 그 중점이 모든 다각형의 안쪽에 있는지도 판정했다.&lt;/s&gt; 수정 요청이 반영되었으며, 재채점까지 완료되었다.&lt;s&gt;&lt;/s&gt;&lt;/p&gt;</description>
      <category>알고리즘/BOJ</category>
      <category>2125</category>
      <category>boj</category>
      <category>백준</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/29</guid>
      <comments>https://kimhwon.tistory.com/29#entry29comment</comments>
      <pubDate>Fri, 23 Apr 2021 22:11:32 +0900</pubDate>
    </item>
    <item>
      <title>13466번: Endless Turning</title>
      <link>https://kimhwon.tistory.com/28</link>
      <description>&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/13466&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.acmicpc.net/problem/13466&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;13466번: Endless Turning&quot; data-og-description=&quot;Last week your little sister celebrated her birthday, and&amp;nbsp;she was very pleased with her birthday present: a brand&amp;nbsp;new scooter! Since then several times a day she goes&amp;nbsp;for a drive, without telling anyone. She will leave the&amp;nbsp;house, and go right on the pa&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/13466&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lJtKO/hyJUU1eHT0/hxtVCO0JKEhZ6l0VrgwHvK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot; data-og-url=&quot;https://www.acmicpc.net/problem/13466&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/13466&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/13466&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lJtKO/hyJUU1eHT0/hxtVCO0JKEhZ6l0VrgwHvK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;13466번: Endless Turning&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Last week your little sister celebrated her birthday, and&amp;nbsp;she was very pleased with her birthday present: a brand&amp;nbsp;new scooter! Since then several times a day she goes&amp;nbsp;for a drive, without telling anyone. She will leave the&amp;nbsp;house, and go right on the pa&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;시작점과 정수 N, R개의 직선이 주어진다. 시작점에서 직선을 따라 가다가 교차점을 만나면 오른쪽으로 돈다. N번 회전을 했을 때 어느 직선에 있는지 찾는 문제다.&lt;br /&gt;&lt;br /&gt;N이 10^10이나 되기 때문에 단순한 시뮬레이션은 어려울 것처럼 보인다. 그런데 직선이 100개로 매우 적기 때문에 같은 교차점을 계속 순회할 것이라고 추측해 볼 수 있다.&lt;br /&gt;&lt;br /&gt;잘 생각해 보면 교차점에서 무조건 오른쪽으로만 회전하므로 지나간 경로는 볼록다각형 형태로 나타날 것이다. 100개의 직선으로 만들 수 있는 꼭짓점이 가장 많은 볼록다각형 즉, 최대한 다양한 교차점을 지나는 경로는 100각형 형태다. 따라서 최대 100개의 교차점만 지나간다는 뜻이고, 시작점으로 돌아올 때까지만 시뮬레이션을 할 수 있다.&lt;br /&gt;&lt;br /&gt;R이 작으므로 O(R^2)으로 각 직선끼리의 교점을 다 구한다. 각 직선마다 어느 지점에서 누구와 교차하는지 저장해 두고, 그 교점으로 정렬해두면 쉽게 구현할 수 있다.(vector&amp;lt;Cross&amp;gt; adj[]) lower_bound() 또는 upper_bound()를 잘 활용하면 어떤 직선에서 교점을 알 때, 그 교점에 바로 왼쪽이나 오른쪽으로 인접한 다른 교점을 O(log(R))에 찾을 수 있다.(Cross getNext(const Cross&amp;amp; me, int&amp;amp; dir)) 찾은 새로운 교점에 연결된 다른 직선에 대하여, 같은 방식으로 인접한 또다른 교차점을 찾아 나가면 된다. 시작한 직선으로 돌아올 때까지를 한 사이클이라고 하면, 사이클의 N % (사이클 길이) 번째 직선이 답이다.&lt;br /&gt;&lt;br /&gt;모든 교점에 대하여 인접한 교점을 찾는데 총 O(R log(R))이지만 맨 처음에 모든 직선에 대한 교점을 만드는데 O(R^2)이므로, O(R^2)으로 해결할 수 있다.&lt;br /&gt;&lt;br /&gt;코드&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;text-align: justify;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://boj.kr/5ad16e0600ab4e49b0065459a61f6c0a&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;boj.kr/5ad16e0600ab4e49b0065459a61f6c0a&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>알고리즘/BOJ</category>
      <category>13466</category>
      <category>boj</category>
      <category>백준</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/28</guid>
      <comments>https://kimhwon.tistory.com/28#entry28comment</comments>
      <pubDate>Sat, 17 Apr 2021 12:55:40 +0900</pubDate>
    </item>
    <item>
      <title>15004번: Bearly Made It</title>
      <link>https://kimhwon.tistory.com/27</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15004&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.acmicpc.net/problem/15004&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618470541708&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;15004번: Bearly Made It&quot; data-og-description=&quot;Barney the polar has wandered off on an adventure. Lost in thought, he suddenly realizes he has strayed too far from his mother and is stuck on an ice shelf. He can still see her in the distance, but the only way back is by crossing a group of other ice sh&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;https://www.acmicpc.net/problem/15004&quot; data-og-url=&quot;https://www.acmicpc.net/problem/15004&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bJ9igO/hyJTC7BMHK/wESs5HXmsVI39pZefhL78K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/eA2Rr/hyJTJMrOoV/ei9mCgGOCfzJ2SH18SNOrk/img.png?width=526&amp;amp;height=512&amp;amp;face=0_0_526_512&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/15004&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.acmicpc.net/problem/15004&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bJ9igO/hyJTC7BMHK/wESs5HXmsVI39pZefhL78K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/eA2Rr/hyJTJMrOoV/ei9mCgGOCfzJ2SH18SNOrk/img.png?width=526&amp;amp;height=512&amp;amp;face=0_0_526_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;15004번: Bearly Made It&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Barney the polar has wandered off on an adventure. Lost in thought, he suddenly realizes he has strayed too far from his mother and is stuck on an ice shelf. He can still see her in the distance, but the only way back is by crossing a group of other ice sh&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시점과 종점, 여러 원들이 주어진다. 시점에서 원 내부만 지나면서 종점에 도착하고자 할 때 최단 경로의 길이 (또는 불가능한지)를 구하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 자명한 점은 &lt;span style=&quot;color: #333333;&quot;&gt;시점에서 종점으로 직선으로 가는 경우가 아니라면 최단경로는&lt;/span&gt; 무조건 원과 원 사이 교점을 지나야 한다는 것이다. 문제에 제시된 그림에 메모했다. &lt;span style=&quot;color: #333333;&quot;&gt;(파랑)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;350&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G43MA/btq2E8hRmD8/4mX1hmG5IIUvF9sUDrah4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G43MA/btq2E8hRmD8/4mX1hmG5IIUvF9sUDrah4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G43MA/btq2E8hRmD8/4mX1hmG5IIUvF9sUDrah4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG43MA%2Fbtq2E8hRmD8%2F4mX1hmG5IIUvF9sUDrah4K%2Fimg.png&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;350&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;잘 생각해보면 코너를 돌 때 최단으로 이동하는 방법은 코너에 최대한 붙어서 이동하는 것이다. 즉, 코너가 되는 지점인 교점을 지나쳐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N이 25밖에 되지 않으므로 원들 사이 모든 교점을 구하고, 각 교점들과 시점, 종점을 모두 잇는 선분을 만든다. 선분을 따라 이동하는 최단 경로를 다익스트라 등으로 구할 수 있다. 여기서 각 선분이 가능한지 즉, 원 바깥으로 나가지 않는지 판정하는 것이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원과 원 사이 교점을 구하는 식은 &lt;a href=&quot;https://stackoverflow.com/questions/3349125/circle-circle-intersection-points&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;i&gt;여기&lt;/i&gt;&lt;/a&gt;를 참고하여 O(N^2)으로 모든 원 사이에 교점들을 다 찾았다.(tuple&amp;lt;int, Point, Point&amp;gt; intersect(Circle c1, Circle c2) 함수) 다시 N^2 = M개의 각 교점들을 O(M^2)으로 선분을 만들어보고 가능한지 체크한다.(bool incLine(Line ln, vector&amp;lt;Circle&amp;gt; &amp;amp;cir) 함수) 주의할 점은 시점에서 교점으로, 또는 종점에서 교점으로, 시점에서 종점으로 바로 갈 수도 있으므로 시점과 종점도 포함해서 생각해야 한다. 선분을 만들 수 있다면, 그래프에 간선으로 추가하고 다익스트라를 사용해서 최단 경로를 찾는다.(ld dijkstra(ll start, ll end))&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 시간복잡도는 O(ElogV)인데, 여기서 E = M^2 = N^4, V = N^2 이므로 O(N^4 log N)이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;튜플 처음 배우고 짠거라 함수 생긴게 좀 더럽다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://boj.kr/76c073b38f8d4ec795270874bf90a010&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;boj.kr/76c073b38f8d4ec795270874bf90a010&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618472279295&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;공유 소스 보기&quot; data-og-description=&quot;// 15004 Bearly Made It #include #define TEST int tt; cin &amp;gt;&amp;gt; tt; while (tt--) #define all(v) (v).begin(), (v).end() #define loop(e, v) for (auto&amp;amp; (e) : (v)) #define pii pair #define pll pair #define xx first #define yy second #define ll long long #define l&quot; data-og-host=&quot;www.acmicpc.net&quot; data-og-source-url=&quot;http://boj.kr/76c073b38f8d4ec795270874bf90a010&quot; data-og-url=&quot;https://www.acmicpc.net/source/share/76c073b38f8d4ec795270874bf90a010&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/7ybRD/hyJTHukCgr/hIODDQP5HvZ1pmbwE0Mgt1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;http://boj.kr/76c073b38f8d4ec795270874bf90a010&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;http://boj.kr/76c073b38f8d4ec795270874bf90a010&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/7ybRD/hyJTHukCgr/hIODDQP5HvZ1pmbwE0Mgt1/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;공유 소스 보기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;// 15004 Bearly Made It #include #define TEST int tt; cin &amp;gt;&amp;gt; tt; while (tt--) #define all(v) (v).begin(), (v).end() #define loop(e, v) for (auto&amp;amp; (e) : (v)) #define pii pair #define pll pair #define xx first #define yy second #define ll long long #define l&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.acmicpc.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;tuple&amp;lt;int, Point, Point&amp;gt; intersect(Circle c1, Circle c2)&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a style=&quot;letter-spacing: 0px;&quot; href=&quot;http://stackoverflow.com/questions/3349125/circle-circle-intersection-points&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;stackoverflow.com/questions/3349125/circle-circle-intersection-points&lt;/a&gt; 을 참고했다.&lt;/li&gt;
&lt;li&gt;리턴 튜플의 첫 원소는 교점의 갯수, 두번째와 세번째 원소는 교점이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;caret-color: auto; letter-spacing: 0px;&quot;&gt;bool incLine(Line ln, vector&amp;lt;Circle&amp;gt; &amp;amp;cir)&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;caret-color: auto; letter-spacing: 0px;&quot;&gt;선분과 원의 교점을 다 구하고, 정렬한다. 교점들을 스윕하면서 원에 들어가면 depth를 증가하고 원 바깥으로 나가면 depth를 감소한다. depth가 0인 영역 즉, 원 바깥에 있는 영역이 있는지 확인한다. 이 때 주의할 점은 직선이 아니라 선분이므로, 선분의 시작점과 끝점까지만 스윕을 해야 한다.&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;caret-color: auto; letter-spacing: 0px;&quot;&gt;원과 직선의 교점 판정은 이어지는 &lt;/span&gt;tuple&amp;lt;int, ld, ld&amp;gt; intersect(Line ln, Circle cc)으로 했다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;caret-color: auto; letter-spacing: 0px;&quot;&gt;tuple&amp;lt;int, ld, ld&amp;gt; intersect(Line ln, Circle cc)&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;caret-color: auto; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;a style=&quot;letter-spacing: 0px;&quot; href=&quot;https://math.stackexchange.com/questions/311921/get-location-of-vector-circle-intersection&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;math.stackexchange.com/questions/311921/get-location-of-vector-circle-intersection&lt;/a&gt; 을 참고했다.&lt;/li&gt;
&lt;li&gt;리턴 튜플의 첫 원소는 교점의 갯수, 두번째와 세번째 원소는 교점까지 거리이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;caret-color: auto; letter-spacing: 0px;&quot;&gt;ld dijkstra(ll start, ll end)&lt;/span&gt;&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;caret-color: auto; letter-spacing: 0px;&quot;&gt;그냥 다익스트라 함수. 자료형만 ld로 바꿨다. 실수 오차 신경 안썼는데 괜찮은 것 같다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>알고리즘/BOJ</category>
      <category>15004</category>
      <category>boj</category>
      <category>백준</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/27</guid>
      <comments>https://kimhwon.tistory.com/27#entry27comment</comments>
      <pubDate>Thu, 15 Apr 2021 17:03:11 +0900</pubDate>
    </item>
    <item>
      <title>Educational Codeforces Round 107 (Rated for Div. 2)</title>
      <link>https://kimhwon.tistory.com/26</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1455&quot; data-origin-height=&quot;147&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cantdt/btq2AGGNAgh/oigTMJ2ZiWNuehoS8TMKlK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cantdt/btq2AGGNAgh/oigTMJ2ZiWNuehoS8TMKlK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cantdt/btq2AGGNAgh/oigTMJ2ZiWNuehoS8TMKlK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcantdt%2Fbtq2AGGNAgh%2FoigTMJ2ZiWNuehoS8TMKlK%2Fimg.png&quot; data-origin-width=&quot;1455&quot; data-origin-height=&quot;147&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 에듀는 마음이 편안하다. 하지만 그렇다고 엄청 잘 풀지는 못해서 블루 복구는 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;A. Review Site&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;upvote하는 사람과 downvote하는 사람은 고정이고, 영화를 보지 않은 사람을 최대한 upvote쪽으로 몰아야 한다. 서버가 2개이므로, 한 서버 쪽으로 upvote하는 사람을 다 보내고 다른 서버 쪽으로는 downvote하는 사람을 다 보내버리자. 그리고 영화를 보지 않은 사람을 upvote만 있는 서버로 보내면, 전부 upvote를 하게 된다.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;B. GCD Length&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;gcd(x, y)를 g, x/g = x', y/g = y'이라고 하자. x', y', g가 모두 소수라면 다른 예외사항 없이 항상 조건을 만족한다. 따라서 g를 c자리 소수, x'을 a-c+1자리 소수, y'을 b-c+1자리 소수로 정한다. 이 때, 곱셈을 해서 자리올림이 생기면 안되므로 가장 작은 소수로 정해야 할 것이다. 1~9자리 가장 작은 소수는 울프람알파로 찾아서 하드코딩하고, x'과 y'이 같으면 gcd가 달라질 수 있으므로 x'을 가장 작은 소수, y'을 두번째로 작은 소수로 정한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;C. Yet Another Card Deck&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;같은 숫자가 여러 개 있어도, 가장 위에 있는 숫자만 움직이므로 인덱스만 저장해두고 좌표압축으로 줄여줄 수 있다. 압축한 수열을 b라고 하면 adj[i]를 b_i 앞에 있는 원소라고 정의해보자.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;760&quot; width=&quot;582&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0nE1H/btq2CFm9dsV/NtfkGukSdZExjIaynhsgm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0nE1H/btq2CFm9dsV/NtfkGukSdZExjIaynhsgm0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0nE1H/btq2CFm9dsV/NtfkGukSdZExjIaynhsgm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0nE1H%2Fbtq2CFm9dsV%2FNtfkGukSdZExjIaynhsgm0%2Fimg.png&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;760&quot; width=&quot;582&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약에 쿼리가 3이 들어왔다면, 저장해 두었던 3의 (압축하기 전) 인덱스를 출력한다. 그리고 맨 앞으로 옮겨야 하는데, 인접 리스트로 모델링하면 손쉽게 핸들링할 수 있다. 그림에서처럼 3의 앞에 있는 원소는 adj[3]의 멤버들(초록)이다. 이들 뒤에 있던 3이 앞으로 이동했으므로, 각 멤버들의 인덱스를 +1 하고, adj[]도 업데이트해준다.(파랑)&amp;nbsp; 각 쿼리에 대해 같은 방식으로 계속 진행해 나가면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;D. Min Cost String&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;인접한 두 문자 한 쌍을 한 요소로 생각해보자. 이 한 쌍을 간선으로 모델링해보면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;371&quot; width=&quot;376&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQ1ynJ/btq2zZGtcgP/ncQYLRFOKAx9IgtdsPIE8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQ1ynJ/btq2zZGtcgP/ncQYLRFOKAx9IgtdsPIE8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQ1ynJ/btq2zZGtcgP/ncQYLRFOKAx9IgtdsPIE8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQ1ynJ%2Fbtq2zZGtcgP%2FncQYLRFOKAx9IgtdsPIE8K%2Fimg.png&quot; data-origin-width=&quot;688&quot; data-origin-height=&quot;371&quot; width=&quot;376&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세 개의 문자가 있을 때 나올 수 있는 모든 요소들은 aa, ab, ac, ba, bb, bc, ca, cb, cc로 총 9가지이다. 이들을 간선으로 만들면 루프+완전그래프 형태가 된다.(파랑)&amp;nbsp; 따라서 문제를 재해석하면 &lt;span style=&quot;color: #333333;&quot;&gt;루프+완전그래프에서 가능한 같은 간선을 지나지 않으면서 순회하는 방법을 찾는 문제가 된다. 각 정점마다 짝수개의 간선이 추가되므로 이 그래프는 무조건 한붓그리기가 가능하고, 오일러 경로가 답이 된다. dfs등으로 오일러 경로를 따라가면서 문자열을 만들고 조건에 맞는 길이만큼 출력하면 된다. 문자열보다 더 긴 길이가 필요하면, 문자열을 한 번 순회하는 것을 한 사이클로 생각하고 여러 번 순회하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;아이디어는 금방 떠올랐으나 오일러 경로를 순회하는 방법을 몰라서 복잡하게 구현했는데, Hierholzer's Algorithm이라는 dfs 비스무리한 아주 웰노운한 방법이 있다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;E. Colorings and Dominoes (업솔빙)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Green55의 해설을 듣고서야 이해했다. 풀이는 다음과 같다. &lt;span&gt;먼저 어떤 연속된 두 블록을 딱 고정해놓고 생각해보자. 세로로 두 칸을 고정했다면 &lt;span&gt;파란색으로 칠하고 1점을 얻는게 확정이고, &lt;span&gt;나머지 칸은 상관이 없다. &lt;span&gt;따라서 모든 경우의 수에서 저 두칸에서 얻을 수 있는 점수는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;2^(남은 o의 개수)이다. 당연히 서로 겹치는 사건이 존재하는데, &lt;span&gt;여기서 &quot;가로 두 블록을 R로 고정했음&quot;이라는 사건과 &quot;세로 두 블록을 B로 고정했음&quot;은 겹치지 않으므로 서로 독립적이다. 왜냐하면 어떤 한 칸이 가로 두 블록을 채우면서 세로 두 블록을 채울 수는 없기 때문이다. &lt;span&gt;그러면 결국 겹치는 사건들은, 연속되게 존재하는 칸에서만 발생한다는 것을 알 수 있다. &lt;span&gt;그럼 결국 우리가 궁금한 것은 &quot;n&lt;span&gt;칸이 연속되게 존재할 때, 이 칸에서 얻을 수 있는 점수의 합&quot;이 된다. &lt;span&gt;백트래킹으로 완전탐색을 짜서 돌린 후 &lt;a href=&quot;http://oeis.org/A045883&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;oeis&lt;/a&gt;에 치면 예쁜 점화식이 나오니까 가져다 쓰자. 찾은 점화식을 f(n)이라 하면, 결과적으로 답은 f&lt;span&gt;( (연속된 o의 갯수) - 1 ) * 2^( (o의 총 갯수) - &lt;span style=&quot;color: #333333;&quot;&gt;(연속된 o의 갯수) &lt;/span&gt;) 의 합이 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;애초에 겹치는 사건 분류를 못해서 풀진 못했지만, &lt;/span&gt;oeis를 활용한 답이라니 정신이 혼미해진다. 에디토리얼 뜨기 전에 &lt;a href=&quot;https://codeforces.com/blog/entry/89562?#comment-779753&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;댓글들&lt;/a&gt;을 살펴보니 다들 oeis로 풀은 것 같았다. 에디토리얼의 정해는 마찬가지로 &lt;span style=&quot;color: #333333;&quot;&gt;완전탐색 돌린 후, 규칙을 잘 찾으란건데... 확률이 1/4, 1/4 - 1/8, 1/4 - 1/8 + 1/16, 1/4 - 1/8 + 1/16 - 1/32, ... 이런 형태로 나타난다고 한다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업솔빙 도중에 오버플로우가 안잡혀서 여러 번 틀렸는데, &lt;a href=&quot;https://kimhwon.tistory.com/24&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;템플릿&lt;/a&gt;을 구해서 사용했더니 바로 AC 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/26</guid>
      <comments>https://kimhwon.tistory.com/26#entry26comment</comments>
      <pubDate>Thu, 15 Apr 2021 14:58:02 +0900</pubDate>
    </item>
    <item>
      <title>Divide by Zero 2021 and Codeforces Round #714 (Div. 2)</title>
      <link>https://kimhwon.tistory.com/25</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1458&quot; data-origin-height=&quot;104&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bh5yFc/btq2CJilqJm/DRW3WqebAmTVaHfrZE5R10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bh5yFc/btq2CJilqJm/DRW3WqebAmTVaHfrZE5R10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bh5yFc/btq2CJilqJm/DRW3WqebAmTVaHfrZE5R10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbh5yFc%2Fbtq2CJilqJm%2FDRW3WqebAmTVaHfrZE5R10%2Fimg.png&quot; data-origin-width=&quot;1458&quot; data-origin-height=&quot;104&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어려웠고 결과적으로 망했다. 역시 외부 연계 라운드는 무섭다. 민트로 똑떨함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;A. Array and Peaks&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;일단 가능한 &lt;span&gt;많은 &lt;span&gt;peak이 존재하려면 &lt;span style=&quot;color: #333333;&quot;&gt;peak 좌우에 더 작은 값들이 위치해야 한다. 그러면 한칸 걸러 한칸씩 peak이 등장하는 상태가 최대이고, 따라서 최대 floor( &lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;N&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)/&lt;/span&gt;&lt;span&gt;2 )개의 peak이 존재할 수 있다. 반대로 가장 적게 peak이 존재하는 경우는, 정렬된 상태면 하나도 없는 상태가 된다. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;주어진 peak 갯수만큼, 최대로 만드는 전략으로 채운다. 빈 자리들에 오름차순으로 남은 수들을 채워 넣으면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;B. AND Sequences&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;제일 극단적인 케이스를 생각해보면 &lt;span&gt;a1 = a2 &amp;amp; ... &amp;amp; an 또는 a1 &amp;amp; ... &amp;amp; an-1 = an 일 것이다. 그런데 and 연산을 잘 생각해보면 비트가 꺼질 수는 있어도 켜질 수는 없다. 즉, &lt;span style=&quot;color: #333333;&quot;&gt;a1 = a2 &amp;amp; ... &amp;amp; an 이면서 a1 &amp;amp; ... &amp;amp; an-1 = an&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;를 만족하려면 a2 &amp;amp; ... an-1을 a1 또는 an과 and 연산 했을때, a1이나 an의 비트를 꺼서는 안된다. 따라서 a1 = an이 만족하고, a1 = an = &lt;span style=&quot;color: #333333;&quot;&gt;a1 &amp;amp; ... &amp;amp; an-1 = &lt;span style=&quot;color: #333333;&quot;&gt;a2 &amp;amp; ... &amp;amp; an 이다. &lt;span style=&quot;color: #333333;&quot;&gt;a1 &amp;amp; ... &amp;amp; an-1 =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;a2 &amp;amp; ... &amp;amp; an 이면 &lt;span style=&quot;color: #333333;&quot;&gt;a1 &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt; ... &amp;amp; an = &lt;span style=&quot;color: #333333;&quot;&gt;a1 &amp;amp; ... &amp;amp; an-1 =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;a2 &amp;amp; ... &amp;amp; an 이다.&lt;br /&gt;여기까지 관찰을 하고, 구현을 하면 된다. &lt;span style=&quot;color: #333333;&quot;&gt;a1 &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;... &amp;amp; an을 구하고, &lt;span style=&quot;color: #333333;&quot;&gt;각 원소의 등장 횟수를 센다. a1과 an을 고정하고 a2~an-1에 잘 채워 넣는다고 생각해보면, a1과 an에 하나씩 원소를 배정해보면서 구할 수 있다. 어떤 원소가 2개 이상이면서 &lt;span style=&quot;color: #333333;&quot;&gt;a1 &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;... &amp;amp; an와 같으면 (즉, &lt;span style=&quot;color: #333333;&quot;&gt;a1 = an =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;a1 &amp;amp; ... &amp;amp; an-1 =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;a2 &amp;amp; ... &amp;amp; an&lt;/span&gt;&lt;/span&gt;) 조건에 일치한다. 이 상태의 경우의 수는 &lt;span&gt;(cnt)P(2) * (N-2)! 이다. 페르마 소정리 등을 사용해 경우의 수를 잘 계산하면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;분명 B번인데 뭔가 잘못돼가고 있다는 느낌이 들었다... 체감은 한 C번인데 그냥 A번 풀지 말고 탈주할까 싶었다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;span&gt;C. Add One (업솔빙)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;span&gt;각 숫자들이 변하는 형태는 독립적이므로, 따로 떼어놓고 생각해도 된다. 또한 어떤 숫자 'k'는 '0'이 k번 연산을 한 후와 동치이므로, 0으로 시작할 때의 규칙만 찾으면 된다. 완전탐색 코드를 짜보면 증가량이 이항계수 모양으로 나타난다... 까지 관찰을 하고 못풀었다.&lt;br /&gt;Green55의 풀이는 다음과 같다. &lt;span&gt;여기서 '0'은 10번 연산을 하면 '1' 과 '0'으로 쪼개지니까 &lt;span&gt;('0'이 m초 지난 자릿수) = ('1'이 m-10초 지난 후 자릿수) + ('0'이 m-10초 지난 후 자릿수) 이다. &lt;span&gt;('1'이 m-10초 지난 후 자릿수) 는 위에서 말했다시피 ('0'이 m-9초 지난 후 자릿수) 이다. &lt;span&gt;그러면 &lt;span&gt;('0'이 m초 지난 자릿수) = ('0'이 m-9초 지난 후 자릿수) + ('0'이 m-10초 지난 후 자릿수). 이를 dp식으로 표현하면 &lt;span&gt;dp[m] = dp[m-9] + dp[m-10]이다. 그에 더해, &lt;span style=&quot;color: #333333;&quot;&gt;naive한 수열이 이항계수 비스무리한 형태면,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;점화식이 선형일 확률이 매우 높으므로 벌래캠프로 해결할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;대충 규칙이 있을거라곤 생각했지만, DP를 확실히 못하긴 한다. 연습 좀 더 해야겠다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/25</guid>
      <comments>https://kimhwon.tistory.com/25#entry25comment</comments>
      <pubDate>Thu, 15 Apr 2021 13:29:28 +0900</pubDate>
    </item>
    <item>
      <title>Modulo Integer</title>
      <link>https://kimhwon.tistory.com/24</link>
      <description>&lt;p&gt;overflow에 안전한 int 자료형&lt;/p&gt;
&lt;pre id=&quot;code_1618252040243&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct mint {
    int val;
    mint() { val = 0; }
    mint(const ll&amp;amp; v) {
        val = (-MOD &amp;lt;= v &amp;amp;&amp;amp; v &amp;lt; MOD) ? v : v % MOD;
        if (val &amp;lt; 0) val += MOD;
    }

    friend ostream&amp;amp; operator&amp;lt;&amp;lt;(ostream&amp;amp; os, const mint&amp;amp; a) { return os &amp;lt;&amp;lt; a.val; }
    friend bool operator==(const mint&amp;amp; a, const mint&amp;amp; b) { return a.val == b.val; }
    friend bool operator!=(const mint&amp;amp; a, const mint&amp;amp; b) { return !(a == b); }
    friend bool operator&amp;lt;(const mint&amp;amp; a, const mint&amp;amp; b) { return a.val &amp;lt; b.val; }

    mint operator-() const { return mint(-val); }
    mint&amp;amp; operator+=(const mint&amp;amp; m) { if ((val += m.val) &amp;gt;= MOD) val -= MOD; return *this; }
    mint&amp;amp; operator-=(const mint&amp;amp; m) { if ((val -= m.val) &amp;lt; 0) val += MOD; return *this; }
    mint&amp;amp; operator*=(const mint&amp;amp; m) { val = (ll)val*m.val%MOD; return *this; }
    friend mint ipow(mint a, ll p) {
        mint ans = 1; for (; p; p /= 2, a *= a) if (p&amp;amp;1) ans *= a;
        return ans;
    }
    friend mint inv(const mint&amp;amp; a) { assert(a.val); return ipow(a, MOD - 2); }
    mint&amp;amp; operator/=(const mint&amp;amp; m) { return (*this) *= inv(m); }

    friend mint operator+(mint a, const mint&amp;amp; b) { return a += b; }
    friend mint operator-(mint a, const mint&amp;amp; b) { return a -= b; }
    friend mint operator*(mint a, const mint&amp;amp; b) { return a *= b; }
    friend mint operator/(mint a, const mint&amp;amp; b) { return a /= b; }
    operator int64_t() const { return val; }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/정리글</category>
      <category>c++</category>
      <category>modulo</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/24</guid>
      <comments>https://kimhwon.tistory.com/24#entry24comment</comments>
      <pubDate>Tue, 13 Apr 2021 03:28:15 +0900</pubDate>
    </item>
    <item>
      <title>Policy based data structures</title>
      <link>https://kimhwon.tistory.com/23</link>
      <description>&lt;pre id=&quot;code_1618236407589&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;ext/pb_ds/assoc_container.hpp&amp;gt;
#include &amp;lt;ext/pb_ds/tree_policy.hpp&amp;gt;
using namespace __gnu_pbds;

#define TREE_NODE ll
#define ordered_set tree&amp;lt;TREE_NODE, null_type, less&amp;lt;TREE_NODE&amp;gt;, rb_tree_tag, tree_order_statistics_node_update&amp;gt;
// 중복이 있을 때 less&amp;lt;TREE_NODE&amp;gt; 이면 첫 원소, less_equal&amp;lt;TREE_NODE&amp;gt; 이면 마지막 원소

{
	ordered_set X;
	*X.find_by_order(x);
	X.order_of_key(x);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/blog/entry/11080&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;codeforces.com/blog/entry/11080&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618236428044&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;C++ STL: Policy based data structures - Codeforces&quot; data-og-description=&quot; &quot; data-og-host=&quot;codeforces.com&quot; data-og-source-url=&quot;https://codeforces.com/blog/entry/11080&quot; data-og-url=&quot;https://codeforces.com/blog/entry/11080&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/e0esJ/hyJSdfthpO/I55Bi8ukH6Zcio6CcQ4CV0/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300&quot;&gt;&lt;a href=&quot;https://codeforces.com/blog/entry/11080&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://codeforces.com/blog/entry/11080&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/e0esJ/hyJSdfthpO/I55Bi8ukH6Zcio6CcQ4CV0/img.png?width=300&amp;amp;height=300&amp;amp;face=0_0_300_300');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;C++ STL: Policy based data structures - Codeforces&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;codeforces.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/libstdc++/manual/policy_data_structures_design.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;gcc.gnu.org/onlinedocs/libstdc++/manual/policy_data_structures_design.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618236466532&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Design&quot; data-og-description=&quot;Hash-tables are unfortunately especially susceptible to choice of policies. One of the more complicated aspects of this is that poor combinations of good policies can form a poor container. Following are some considerations. Some combinations do not work w&quot; data-og-host=&quot;gcc.gnu.org&quot; data-og-source-url=&quot;https://gcc.gnu.org/onlinedocs/libstdc++/manual/policy_data_structures_design.html&quot; data-og-url=&quot;https://gcc.gnu.org/onlinedocs/libstdc++/manual/policy_data_structures_design.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/tcpV5/hyJSnI9lRT/jNx2sImEKKpMntNK3BwKmK/img.png?width=813&amp;amp;height=457&amp;amp;face=0_0_813_457&quot;&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/libstdc++/manual/policy_data_structures_design.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gcc.gnu.org/onlinedocs/libstdc++/manual/policy_data_structures_design.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/tcpV5/hyJSnI9lRT/jNx2sImEKKpMntNK3BwKmK/img.png?width=813&amp;amp;height=457&amp;amp;face=0_0_813_457');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Design&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Hash-tables are unfortunately especially susceptible to choice of policies. One of the more complicated aspects of this is that poor combinations of good policies can form a poor container. Following are some considerations. Some combinations do not work w&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;gcc.gnu.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/정리글</category>
      <category>c++</category>
      <category>STL</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/23</guid>
      <comments>https://kimhwon.tistory.com/23#entry23comment</comments>
      <pubDate>Mon, 12 Apr 2021 23:08:03 +0900</pubDate>
    </item>
    <item>
      <title>solved.ac 다이아 달성</title>
      <link>https://kimhwon.tistory.com/22</link>
      <description>&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;figure class=&quot;imageblock floatLeft&quot; width=&quot;421&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caUqrh/btq2nixMWmv/Zupu761cIIkz9Ne60HEmeK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caUqrh/btq2nixMWmv/Zupu761cIIkz9Ne60HEmeK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caUqrh/btq2nixMWmv/Zupu761cIIkz9Ne60HEmeK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaUqrh%2Fbtq2nixMWmv%2FZupu761cIIkz9Ne60HEmeK%2Fimg.png&quot; width=&quot;421&quot; height=&quot;NaN&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj39oV/btq2irvNfof/Uq5Ck7TWs9CyvvqsS7a9IK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj39oV/btq2irvNfof/Uq5Ck7TWs9CyvvqsS7a9IK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj39oV/btq2irvNfof/Uq5Ck7TWs9CyvvqsS7a9IK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj39oV%2Fbtq2irvNfof%2FUq5Ck7TWs9CyvvqsS7a9IK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;solved.ac 레이팅 시스템 바뀌면서 플래1로 올라왔길래 어려운거 위주로 풀어서 다이아까지 갔다. &lt;span style=&quot;color: #333333;&quot;&gt;올리는 김에 학교 2등까지 찍음.&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실력에도 맞지 않는 너무 어려운 문제를 풀어댄 거 같다. 코포 블루가 다이아라니 좀 부끄럽다. 골플이나 밀어야지...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=== 수정1 ===&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 학교 3등됨 ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올라간 김에 기억에 남는 문제들 몇 개를 포스트로 써볼까 한다&lt;/p&gt;</description>
      <category>아무말</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/22</guid>
      <comments>https://kimhwon.tistory.com/22#entry22comment</comments>
      <pubDate>Sun, 11 Apr 2021 21:14:55 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #659 (Div. 2)</title>
      <link>https://kimhwon.tistory.com/21</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1460&quot; data-origin-height=&quot;182&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VF5ZN/btq2oSyOK3V/mFRmAmez9ExSp9nkylp8J0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VF5ZN/btq2oSyOK3V/mFRmAmez9ExSp9nkylp8J0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VF5ZN/btq2oSyOK3V/mFRmAmez9ExSp9nkylp8J0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVF5ZN%2Fbtq2oSyOK3V%2FmFRmAmez9ExSp9nkylp8J0%2Fimg.png&quot; data-origin-width=&quot;1460&quot; data-origin-height=&quot;182&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock floatRight&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;160&quot; width=&quot;382&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dYWyRp/btq2iWhV0xV/81XLf6v41uznIDfPN3hjq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dYWyRp/btq2iWhV0xV/81XLf6v41uznIDfPN3hjq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dYWyRp/btq2iWhV0xV/81XLf6v41uznIDfPN3hjq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdYWyRp%2Fbtq2iWhV0xV%2F81XLf6v41uznIDfPN3hjq0%2Fimg.png&quot; data-origin-width=&quot;686&quot; data-origin-height=&quot;160&quot; width=&quot;382&quot; height=&quot;NaN&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난이도가 좀 괴상하다. B1+B2 푼 사람보다 C푼 사람이 더 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;꾸역꾸역 B2를 밀었더니 Codeforces Anytime에서 오렌지 퍼포먼스가 떴다 ㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A.&amp;nbsp;Common&amp;nbsp;Prefixes&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인접한&amp;nbsp;두&amp;nbsp;문자열의&amp;nbsp;공통&amp;nbsp;prefix의&amp;nbsp;갯수가&amp;nbsp;주어질&amp;nbsp;때,&amp;nbsp;만족하는&amp;nbsp;문자열의&amp;nbsp;배열을&amp;nbsp;출력하는&amp;nbsp;문제.&amp;nbsp;각&amp;nbsp;문자열의&amp;nbsp;한&amp;nbsp;문자에&amp;nbsp;대해서&amp;nbsp;생각해보면,&amp;nbsp;서로&amp;nbsp;같은지&amp;nbsp;다른지만&amp;nbsp;중요하는&amp;nbsp;것을&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;따라서&amp;nbsp;모든&amp;nbsp;문자를&amp;nbsp;a와&amp;nbsp;b로&amp;nbsp;통일해보자.&amp;nbsp;prefix&amp;nbsp;갯수만큼은&amp;nbsp;그대로&amp;nbsp;두고,&amp;nbsp;그&amp;nbsp;이후는&amp;nbsp;이전&amp;nbsp;문자열과&amp;nbsp;다르게&amp;nbsp;선택하면&amp;nbsp;된다.&amp;nbsp;문자열의&amp;nbsp;길이에&amp;nbsp;대한&amp;nbsp;조건이&amp;nbsp;있는데,&amp;nbsp;이미&amp;nbsp;조건을&amp;nbsp;만족했으므로&amp;nbsp;그냥&amp;nbsp;최대&amp;nbsp;길이인&amp;nbsp;200개로&amp;nbsp;꽉&amp;nbsp;채워서&amp;nbsp;만들어도&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;B2. Koa and the Beach&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간에 따른 파도를 { k, k-1, k-2, ... , 2, 1, 0, 1, 2, ... , k-2, k-1, k } 로 변환해보자. 그러면 각 위치에서 존재할 수 있는 시간이 구간으로 나타나게 된다. 시간이 지남에 따라 현재 높이를 잘 관리하면, 현재 높이가 구간 안에 들어가 있는지 확인해줄 수 있다. 만약 모든 구간이 가능한 경우 즉, 시간과 무관하게 항상 가능한 위치가 있다면 원하는 높이로 이동할 수 있다. &lt;br /&gt;현재 높이가 구간 왼쪽에 있다면, 조금 더 기다려서 높이가 낮아지기를 기다릴 수 있다. 반대로 구간 오른쪽에 있다면 더 이상 진행할 수도 없고 기다릴 수도 없기 때문에 실패한다. 이 과정을 시뮬레이션하면 O(n)안에 해결이 가능하므로, 두 문제 모두 해결이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딱봐도 더러워보이는 문제다. 버추얼이라 그냥 망할 각오하고 구현했더니 다행히 맞았다. 레이티드였으면 나도 C로 도망갔을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;C.&amp;nbsp;String&amp;nbsp;Transformation&amp;nbsp;1&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제일&amp;nbsp;먼저,&amp;nbsp;더&amp;nbsp;작은&amp;nbsp;문자로는&amp;nbsp;변경할&amp;nbsp;수&amp;nbsp;없으므로&amp;nbsp;모든&amp;nbsp;문자를&amp;nbsp;순회하면서&amp;nbsp;예외처리해준다. &lt;br /&gt;각&amp;nbsp;문자를&amp;nbsp;변경하는&amp;nbsp;과정을&amp;nbsp;그래프로&amp;nbsp;모델링해보자.&amp;nbsp;어떤&amp;nbsp;문자&amp;nbsp;X를&amp;nbsp;Y로&amp;nbsp;바꾸는&amp;nbsp;것을&amp;nbsp;정점&amp;nbsp;X에서&amp;nbsp;Y로의&amp;nbsp;간선으로&amp;nbsp;표현할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;잘&amp;nbsp;관찰해보면&amp;nbsp;간선의&amp;nbsp;방향이&amp;nbsp;더&amp;nbsp;큰&amp;nbsp;문자&amp;nbsp;방향으로만&amp;nbsp;생기므로,&amp;nbsp;이&amp;nbsp;그래프는&amp;nbsp;DAG임을&amp;nbsp;알&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;즉,&amp;nbsp;DAG에서&amp;nbsp;최소&amp;nbsp;갯수의&amp;nbsp;간선을&amp;nbsp;사용해서&amp;nbsp;모든&amp;nbsp;정점을&amp;nbsp;지나는&amp;nbsp;방법에&amp;nbsp;대한&amp;nbsp;문제가&amp;nbsp;된다.&amp;nbsp;그래프에서&amp;nbsp;모든&amp;nbsp;정점이&amp;nbsp;연결되면서&amp;nbsp;간선의&amp;nbsp;갯수가&amp;nbsp;최소인&amp;nbsp;경우는&amp;nbsp;spanning&amp;nbsp;tree임이&amp;nbsp;자명하다.&amp;nbsp;트리의&amp;nbsp;간선의&amp;nbsp;갯수는&amp;nbsp;(연결된&amp;nbsp;정점의&amp;nbsp;갯수)-1&amp;nbsp;이므로&amp;nbsp;union-find&amp;nbsp;등으로&amp;nbsp;그래프의&amp;nbsp;연결&amp;nbsp;상태를&amp;nbsp;세어주고&amp;nbsp;간선의&amp;nbsp;갯수를&amp;nbsp;계산하면&amp;nbsp;된다.&amp;nbsp;그래프들이&amp;nbsp;서로&amp;nbsp;연결되지&amp;nbsp;않을&amp;nbsp;수도&amp;nbsp;있음에&amp;nbsp;주의하여,&amp;nbsp;각&amp;nbsp;컴포넌트끼리&amp;nbsp;따로&amp;nbsp;계산해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약간 짬밥?으로 풀었다. 아이디어가 없어서 말린 문제들 중에 그래프로 모델링하는 풀이가 많았어서, 뭔가 상태 전이가 있는데 아이디어가 전혀 떠오르지 않으면 그래프로 한번 모델링해보는 경향이 있다. 모델링해보니까 금방 규칙이 보였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/21</guid>
      <comments>https://kimhwon.tistory.com/21#entry21comment</comments>
      <pubDate>Sun, 11 Apr 2021 21:03:09 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #713 (Div. 3)</title>
      <link>https://kimhwon.tistory.com/20</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1455&quot; data-origin-height=&quot;104&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmZlXG/btq2lq3OtNy/QcxRbFG9QBFg7YbVmyOIR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmZlXG/btq2lq3OtNy/QcxRbFG9QBFg7YbVmyOIR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmZlXG/btq2lq3OtNy/QcxRbFG9QBFg7YbVmyOIR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdmZlXG%2Fbtq2lq3OtNy%2FQcxRbFG9QBFg7YbVmyOIR0%2Fimg.png&quot; data-origin-width=&quot;1455&quot; data-origin-height=&quot;104&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딥3라 언레. 너무 급하게 풀어서 그런지 B번에서 뇌절을 심하게 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A. Spy Detected!&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;map을 사용해 등장한 숫자의 개수를 세고, 1개인 원소의 위치를 출력함.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;B. Almost Rectangle&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두&amp;nbsp;점의&amp;nbsp;위치를&amp;nbsp;각각&amp;nbsp;(x1,&amp;nbsp;y1),&amp;nbsp;(x2,&amp;nbsp;y2)라고&amp;nbsp;하면,&amp;nbsp;조건을&amp;nbsp;만족하는&amp;nbsp;위치들은&amp;nbsp;(x1,&amp;nbsp;y1),&amp;nbsp;(x1,&amp;nbsp;y2),&amp;nbsp;(x2,&amp;nbsp;y1),&amp;nbsp;(x2,&amp;nbsp;y2)&amp;nbsp;이다. &lt;br /&gt;그런데&amp;nbsp;만약&amp;nbsp;x1과&amp;nbsp;x2가&amp;nbsp;같거나&amp;nbsp;y1과&amp;nbsp;y2가&amp;nbsp;같으면&amp;nbsp;직사각형&amp;nbsp;모양이&amp;nbsp;나오지&amp;nbsp;않기&amp;nbsp;때문에&amp;nbsp;x'을&amp;nbsp;임의로&amp;nbsp;x1+1&amp;nbsp;또는&amp;nbsp;x1-1로&amp;nbsp;정할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;둘&amp;nbsp;중에&amp;nbsp;가능한&amp;nbsp;것&amp;nbsp;하나를&amp;nbsp;골라서&amp;nbsp;새로운&amp;nbsp;위치로&amp;nbsp;지정한다.&amp;nbsp;마찬가지로&amp;nbsp;y에&amp;nbsp;대해서도&amp;nbsp;y'을&amp;nbsp;잘&amp;nbsp;정한다. &lt;br /&gt;쉬운 문제였지만 x' 또는 y'이 가능한지 확인을 제대로 하지 못해서 두 번이나 틀렸다. 너무 긴장해서 급하게 제출했던 것 같다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;C.&amp;nbsp;A-B&amp;nbsp;Palindrome&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;constructive하게 해결이 가능하다. 수열에서 0의 갯수와 1의 갯수가 주어지므로(각각 a와 b), 입력된 수열에서&amp;nbsp;이미&amp;nbsp;정해진&amp;nbsp;숫자만큼&amp;nbsp;미리&amp;nbsp;센다.&amp;nbsp;만약에&amp;nbsp;a나&amp;nbsp;b가&amp;nbsp;음수가&amp;nbsp;되면&amp;nbsp;더&amp;nbsp;볼&amp;nbsp;것도&amp;nbsp;없이&amp;nbsp;불가능한&amp;nbsp;상태이다. &lt;br /&gt;수열을&amp;nbsp;한&amp;nbsp;번&amp;nbsp;순회하면서&amp;nbsp;S[i]&amp;nbsp;==&amp;nbsp;S[N-1-i]를&amp;nbsp;만족하도록&amp;nbsp;?를&amp;nbsp;가능한대로&amp;nbsp;채워&amp;nbsp;넣는다.&amp;nbsp;동시에&amp;nbsp;a와&amp;nbsp;b를&amp;nbsp;소모하면서&amp;nbsp;음수가&amp;nbsp;되지&amp;nbsp;않는지&amp;nbsp;확인한다.&amp;nbsp;이렇게&amp;nbsp;하여&amp;nbsp;먼저&amp;nbsp;자명한&amp;nbsp;숫자들에&amp;nbsp;대해서&amp;nbsp;팰린드롬을&amp;nbsp;만족하게&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;남는 ?들에는 숫자를 가능한대로 채워 넣는다. 다 채웠을 때 a나 b가 음수가 되면 불가능한 상태임을 알 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;D. Corrupted Array&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 미리 주어진 수열의 합을 구해둔다. 그 후 주어진 수열 b를 순회하면서 b에서 제외할 숫자 x를 정한다. 수열의 총 합에서 x를 뺀 값은, a의 각 원소들과 a의 모든 원소의 합이다. 다시 말해서 (a의 합)*2이라는 뜻이다. 이를 2로 나눈 뒤 (나눠지지 않으면 예외처리한다.) 그 값이 b에 존재하는지 set등을 사용해 확인한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;br /&gt;E. Permutation by Sum&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구간&amp;nbsp;[L,&amp;nbsp;R]에&amp;nbsp;대해서&amp;nbsp;가장&amp;nbsp;작은&amp;nbsp;경우는&amp;nbsp;[1,&amp;nbsp;2,&amp;nbsp;...&amp;nbsp;,&amp;nbsp;L-R+1]이고&amp;nbsp;가장&amp;nbsp;큰&amp;nbsp;경우는&amp;nbsp;[N,&amp;nbsp;N-1,&amp;nbsp;...&amp;nbsp;,&amp;nbsp;N-(L-R+1)]이다.&amp;nbsp;S가&amp;nbsp;가장&amp;nbsp;작은&amp;nbsp;경우랑&amp;nbsp;큰&amp;nbsp;경우&amp;nbsp;바깥이면&amp;nbsp;불가능하다.&amp;nbsp;반대로&amp;nbsp;가장&amp;nbsp;작은&amp;nbsp;경우랑&amp;nbsp;큰&amp;nbsp;경우&amp;nbsp;안쪽에선&amp;nbsp;S를&amp;nbsp;만족하는&amp;nbsp;수열이&amp;nbsp;항상&amp;nbsp;존재한다. &lt;br /&gt;만약&amp;nbsp;가장&amp;nbsp;작은&amp;nbsp;경우에&amp;nbsp;모든&amp;nbsp;원소에&amp;nbsp;1씩&amp;nbsp;더해준다고&amp;nbsp;하면,&amp;nbsp;구간합이&amp;nbsp;L-R+1씩&amp;nbsp;증가한다.&amp;nbsp;그런데&amp;nbsp;구간의&amp;nbsp;길이가&amp;nbsp;L-R+1이므로&amp;nbsp;한&amp;nbsp;원소씩&amp;nbsp;더해주면&amp;nbsp;사이에&amp;nbsp;모든&amp;nbsp;공간이&amp;nbsp;채워진다. &lt;br /&gt;큰&amp;nbsp;원소부터&amp;nbsp;하나씩&amp;nbsp;더해나가면&amp;nbsp;구간&amp;nbsp;[L,&amp;nbsp;R]의&amp;nbsp;합이&amp;nbsp;S면서&amp;nbsp;항상&amp;nbsp;서로&amp;nbsp;겹치지&amp;nbsp;않는&amp;nbsp;수들의&amp;nbsp;집합으로&amp;nbsp;만들&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;[L,&amp;nbsp;R]을&amp;nbsp;잘&amp;nbsp;구성하고&amp;nbsp;남은&amp;nbsp;위치들에&amp;nbsp;아직&amp;nbsp;사용되지&amp;nbsp;않은&amp;nbsp;수를&amp;nbsp;적절히&amp;nbsp;채워&amp;nbsp;넣으면&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;F. Education (업솔빙)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 위치에서 가진 돈을 일차함수로 그려보면 CHT 처럼 나타난다. O(n)으로 시뮬레이션하면서, 현재 일차식과 다른 일차식을 비교해서 목표하는 돈을 먼저 모으는 쪽으로 계속 업데이트해 나가면 된다.&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/20</guid>
      <comments>https://kimhwon.tistory.com/20#entry20comment</comments>
      <pubDate>Sun, 11 Apr 2021 20:50:36 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #712 (Div. 2)</title>
      <link>https://kimhwon.tistory.com/19</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1463&quot; data-origin-height=&quot;110&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PJszs/btq2irP1JKI/bs7MRhuW8zmESoQrIlli71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PJszs/btq2irP1JKI/bs7MRhuW8zmESoQrIlli71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PJszs/btq2irP1JKI/bs7MRhuW8zmESoQrIlli71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPJszs%2Fbtq2irP1JKI%2Fbs7MRhuW8zmESoQrIlli71%2Fimg.png&quot; data-origin-width=&quot;1463&quot; data-origin-height=&quot;110&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C번에서 엄청 말렸다. 결과는 똑떨.&amp;nbsp; 아슬아슬하게 1600점 파킹했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학기 시작하고 PS를 자주 못하니 실력이 떨어지는게 눈에 보이기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;A. D&amp;eacute;j&amp;agrave; Vu&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처음 주어진 문자열이 팰린드롬이라면 정가운데를 제외하고 어디에 넣든지 팰린드롬이 아니게 된다. 주어진 문자열이 팰린드롬이 아닌데 a를 넣어 팰린드롬이 되는 경우를 생각해보면, 만약 맨 뒤에 a를 추가해 팰린드롬이 되었다면 반대로 맨 앞에 a를 추가한 경우는 전자를 왼쪽 쉬프트한 문자열이고 반대도 마찬가지다. 따라서 둘 중 하나는 무조건 팰린드롬이 아니게 된다. 따라서 처음 주어진 문자열의 맨 앞 또는 맨 뒤에 a를 추가해보고 둘 다 팰린드롬이 나오는 경우만 제외한 모든 경우가 불가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;B. Flip the Bits&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;주어진 문자열을 반전시킬 수 있는 조건은 그 부분수열의 0의 개수와 1의 개수가 같아야 한다. 그런데 0과 1의 개수가 같으므로 반전시킨다고 해도 같다는 것이 보장되며, 처음 상태에서 0과 1의 개수가 같기만 하면 얼마든지 연산을 적용해도 성립함을 알 수 있다. 따라서 주어진 문자열을 뒤에서부터 확인하면서 두 문자열이 같아지도록 마음대로 뒤집으면 된다. 반전하지 못하는 경우가 생기면 실패이고, 아니면 성공이다. 뒤집어진 상태를 boolean 으로 플래그를 정해서 관리하면 편리하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;C. Balance the Bits&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;일단 괄호 문자열의 시작점은 여는 괄호, 끝점은 닫는 괄호임이 자명하다. 따라서 두 괄호문자열의 시작점과 끝점은 동일해야 하므로 둘다 1로 표시되어야 한다. 또한 첫 번째 괄호 문자열이 성립한다고 가정했을 때 두 번째 괄호 문자열도 성립하려면, 첫 번째 괄호 문자열에서 짝수 개의 괄호가 바뀌어야 한다. 따라서 주어진 수열에 1과 0이 모두 짝수 개 등장해야 한다. 이 조건을 만족하면 모두 성립한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;괄호 문자열을 construct하는 방법은, 첫 번째 괄호 문자열을 ()()()... 이런 식으로 정한다. 두 번째 괄호 문자열은 첫 번째에 맞춰서 정한다. 두 개씩 끊어서 하나로 보고, 두 번째 문자열이 성립하지 않으면 반전시키고 첫 번째 문자열도 함께 반전시킨다. 이렇게 되면 첫 번째 괄호 문자열은 () 또는 )(로만 이루어지는데 이는 항상 성립하는 형태이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/19</guid>
      <comments>https://kimhwon.tistory.com/19#entry19comment</comments>
      <pubDate>Sun, 11 Apr 2021 20:42:21 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #710 (Div. 3)</title>
      <link>https://kimhwon.tistory.com/18</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1185&quot; data-origin-height=&quot;107&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oFn3H/btq2kBxNLlc/zRiGHBAEk1r8kST9uqrb7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oFn3H/btq2kBxNLlc/zRiGHBAEk1r8kST9uqrb7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oFn3H/btq2kBxNLlc/zRiGHBAEk1r8kST9uqrb7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoFn3H%2Fbtq2kBxNLlc%2FzRiGHBAEk1r8kST9uqrb7K%2Fimg.png&quot; data-origin-width=&quot;1185&quot; data-origin-height=&quot;107&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Expert라 언레다. 푼 사람 수를 보면 F,G도 풀었어야하는데 좀 아쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;A. Strange Table&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;n x m 행렬 A에서 A_ij 를 알 때, A_ji를 구하는 문제. 행과 열을 나눈 몫과 나머지를 다시 조합해서 해결.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;B. Partial Replacement&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;주어진 문자열에서 정해진 위치만 x로 바꿀 수 있다. 최소한으로 바꿔서 각 x들 사이 거리가 k 미만이 되도록 하는 문제. 왼쪽 끝과 오른쪽 끝은 문제에서 무조건 바꾸라고 하였으니 그대로 바꾼다. 양 끝의 바뀐 x들 사이를 순회하면서, 길이가 k 이상이 되는 지점 직전을 교체해 나간다. 왼쪽 끝과 오른쪽 끝 사이 길이는 고정이니, 어떻게 바꾸던지 (r-l+1)/k 개 교환됨은 자명하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;C. Double-ended Strings&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;문자열의 맨 앞 글자 또는 맨 뒷 글자를 제거할 수 있다. 최소한으로 제거하여 두 문자열이 일치하게 만드는 문제. 두 문자열의 길이가 20으로 매우 짧으므로, 첫 번째 문자열의 모든 substring, 두 번째 문자열의 모든 substring을 비교할 수 있다. 가능한 긴 공통 substring을 찾으면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;D. Epic Transformation&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;주어진 수열에서 서로 다른 임의의 두 원소를 고르고, 고른 둘을 없앨 수 있다. 만들 수 있는 수열의 최소 크기를 구하는 문제. 해석해보면 &lt;a href=&quot;https://www.acmicpc.net/problem/19590&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;www.acmicpc.net/problem/19590&lt;/a&gt; 이 문제와 일치한다. 즉, 수열에서 가장 많은 원소가 절반 이하면 무조건 가능하고, 절반 이상이면 절반을 넘는 만큼 남는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;E. Restoring the Permutation&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;주어진 수열에서 원소의 값이 바뀌었다는 것은 원본 수열의 해당 위치가 새로운 최댓값이라는 뜻이며, 그렇지 않다는 것은 원본 수열의 해당 위치에 현재 최대값 이하의 원소가 있다는 뜻이다. 수열의 값이 바뀌는 지점에서는 원본 수열의 값이 자명하므로 고정하고, 남은 위치들을 조건에 맞게 적절히 채워 나가면 된다. 최소 수열을 만드려면, 가능한 작은 값을 앞에서부터 채워 나가면 된다. 한편, 최대 수열의 경우는 가능한 큰 값을 앞에서부터 채워 나가야 하는데 현재 최댓값 이하의 원소가 있어야 하므로, set을 사용해 upper_bound-1 값으로 채워 나가면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/18</guid>
      <comments>https://kimhwon.tistory.com/18#entry18comment</comments>
      <pubDate>Sun, 11 Apr 2021 20:38:54 +0900</pubDate>
    </item>
    <item>
      <title>네트워크 플로우</title>
      <link>https://kimhwon.tistory.com/17</link>
      <description>&lt;p&gt;이분매칭 : O(V+E)&lt;/p&gt;
&lt;pre id=&quot;code_1616515899563&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct BiMatch {
    bool vst[MAX];
    int match[MAX];     // match[i] &amp;lt;-match-- i
    vector&amp;lt;int&amp;gt; adj[MAX];
    bool dfs(int here) {
        if (vst[here]) return false;
        vst[here] = true;
        for (auto there : adj[here]) {
            if (match[there]&amp;lt;0 || dfs(match[there])) {
                //매칭이 되어있지 않은 정점을 만나거나 이미 매칭된 정점이 다른 정점과 매칭이 가능할 때
                match[there] = here;
                return true;
            }
        }
        return false;
    }
    int bimatch(int cap = 1, int n = MAX-1) { // 1-index
        memset(match, -1, sizeof(match));
        int ret = 0;
        for (int i = 1; i &amp;lt;= n; i++) {
            for (int j = 0; j &amp;lt; cap; ++j) { // st당 몇 번 매칭?
                memset(vst, 0, sizeof(vst));
                if (dfs(i)) ret++;
            }
        }
        return ret;
    }
} BI;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;디닉 : &lt;span&gt;O(EV^2), 0-1 cap에서 min{O(EV^(2/3), O(E^(3/2))}&amp;nbsp; &amp;nbsp;(대충 다익스트라랑 비슷하다고 하자 (ainta 피셜))&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1617701447124&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct Dinic {
    struct edg {int pos, cap, rev;};
    vector&amp;lt;edg&amp;gt; adj[MAX];
    void clear() { for (int i = 0; i &amp;lt; MAX; i++) adj[i].clear(); }
    void make_edge(int s, int e, int x) {
        adj[s].push_back({e, x, (int) adj[e].size()});
        adj[e].push_back({s, 0, (int) adj[s].size() - 1});
    }
    int dis[MAX], pnt[MAX];
    bool bfs(int src, int sink) {
        memset(dis, 0, sizeof(dis));
        memset(pnt, 0, sizeof(pnt));
        queue&amp;lt;int&amp;gt; que;
        que.push(src);
        dis[src] = 1;
        while (!que.empty()) {
            int x = que.front();
            que.pop();
            for (auto &amp;amp;e : adj[x]) {
                if (e.cap &amp;gt; 0 &amp;amp;&amp;amp; !dis[e.pos]) {
                    dis[e.pos] = dis[x] + 1;
                    que.push(e.pos);
                }
            }
        }
        return dis[sink] &amp;gt; 0;
    }
    int dfs(int x, int sink, int f) {
        if (x == sink) return f;
        for (; pnt[x] &amp;lt; adj[x].size(); pnt[x]++) {
            edg e = adj[x][pnt[x]];
            if (e.cap &amp;gt; 0 &amp;amp;&amp;amp; dis[e.pos] == dis[x] + 1) {
                int w = dfs(e.pos, sink, min(f, e.cap));
                if (w) {
                    adj[x][pnt[x]].cap -= w;
                    adj[e.pos][e.rev].cap += w;
                    return w;
                }
            }
        }
        return 0;
    }
    ll maxflow(int src, int sink) {
        ll ret = 0;
        while (bfs(src, sink)) {
            int r;
            while ((r = dfs(src, sink, 2e9))) ret += r;
        }
        return ret;
    }
} FW;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/정리글</category>
      <category>flow</category>
      <category>network flow</category>
      <category>네트워크 플로우</category>
      <category>이분매칭</category>
      <category>플로우</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/17</guid>
      <comments>https://kimhwon.tistory.com/17#entry17comment</comments>
      <pubDate>Wed, 24 Mar 2021 01:12:32 +0900</pubDate>
    </item>
    <item>
      <title>그리디</title>
      <link>https://kimhwon.tistory.com/16</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;반례찾기
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;지금 나에게 최적인 거를 뒤에놈들을 위해서 아껴야 최적인 경우가 존재한가? -&amp;gt; 반례&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2개 요소를 쓰는 그리디&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;a style=&quot;letter-spacing: 0px;&quot; href=&quot;https://www.acmicpc.net/problem/1202&quot;&gt;www.acmicpc.net/problem/1202&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;작은 가방부터 제일 비싼거를 담기&lt;/li&gt;
&lt;li&gt;왜냐면 뒤에서 쓸 가방은 더 유리한 가방이니까... 내가 최선을 골라도 뒤에선 알아서 최선을 고를 수 있다&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/정리글</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/16</guid>
      <comments>https://kimhwon.tistory.com/16#entry16comment</comments>
      <pubDate>Fri, 19 Feb 2021 02:40:59 +0900</pubDate>
    </item>
    <item>
      <title>기하</title>
      <link>https://kimhwon.tistory.com/15</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;유클리드 거리&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;교차판정 할 때, ccw 결과값에 sign 씌우는게 좋다 (오버플로)&lt;/li&gt;
&lt;li&gt;rotate matrix : [cos, -sin // sin, cos]&amp;nbsp; : 꼬마신신고&lt;/li&gt;
&lt;li&gt;벡터
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;vec = (ed - st), sum(vec) = sum(ed) - sum(ed)&lt;/li&gt;
&lt;li&gt;AB = OB - OA (종점 - 시점)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;맨하탄 거리&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-ke-size=&quot;size18&quot;&gt;원이 마름모꼴
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li data-ke-size=&quot;size18&quot;&gt;(x+y, y-x) 로 45도 회전해서 정사각형으로 핸들링&lt;/li&gt;
&lt;li data-ke-size=&quot;size18&quot;&gt;[x, y] * [cos(45), -sin(45) // sin(45), cos(45)] 로 rotation matrix를 곱한 것 (에다가 sq2 상수배 곱함)&lt;/li&gt;
&lt;li data-ke-size=&quot;size18&quot;&gt;당연히 역과정은 성립 안함&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;각 점들에서 거리의 합이 최소인 지점
&lt;ul style=&quot;list-style-type: disc;&quot;&gt;
&lt;li&gt;(x좌표 중앙값, y좌표 중앙값)&lt;/li&gt;
&lt;li&gt;짝수개면 두 점 사이 아무데나&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>알고리즘/정리글</category>
      <category>기하</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/15</guid>
      <comments>https://kimhwon.tistory.com/15#entry15comment</comments>
      <pubDate>Fri, 19 Feb 2021 02:24:49 +0900</pubDate>
    </item>
    <item>
      <title>Green55 블로그 펌 : 어려운 알고리즘 권하는 사회</title>
      <link>https://kimhwon.tistory.com/14</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 글이라 공감이 되어 가져왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blog.naver.com/pasdfq/222217957003&quot;&gt;https://blog.naver.com/pasdfq/222217957003&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1611737725401&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;의식의 흐름 : 어려운 알고리즘 권하는 사회&quot; data-og-description=&quot;* 이 글은 저의 개인적인 생각을 다루고 있습니다. ​​PS를 하는 이유는 크게 3가지 정도 있는거 같은데...&quot; data-og-host=&quot;blog.naver.com&quot; data-og-source-url=&quot;https://blog.naver.com/pasdfq/222217957003&quot; data-og-url=&quot;https://blog.naver.com/pasdfq/222217957003&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cjD74u/hyI54wFFTe/90wfutDcJiefWX4r3y6kQ1/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270&quot;&gt;&lt;a href=&quot;https://blog.naver.com/pasdfq/222217957003&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blog.naver.com/pasdfq/222217957003&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cjD74u/hyI54wFFTe/90wfutDcJiefWX4r3y6kQ1/img.png?width=270&amp;amp;height=270&amp;amp;face=0_0_270_270');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;의식의 흐름 : 어려운 알고리즘 권하는 사회&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;* 이 글은 저의 개인적인 생각을 다루고 있습니다. ​​PS를 하는 이유는 크게 3가지 정도 있는거 같은데...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blog.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/14</guid>
      <comments>https://kimhwon.tistory.com/14#entry14comment</comments>
      <pubDate>Wed, 27 Jan 2021 17:56:07 +0900</pubDate>
    </item>
    <item>
      <title>세그먼트 트리</title>
      <link>https://kimhwon.tistory.com/13</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정당성
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;세그 : 교환법칙 성립&lt;/li&gt;
&lt;li&gt;펜윅 : 교환법칙 성립, 역연산 존재 (ex. +와 -, xor과 xor)&lt;/li&gt;
&lt;li&gt;레이지 : 교환법칙 성립, 구간 update할 값을 O(1)에 계산 가능 (ex. +v : +(r-l+1)*v )&lt;/li&gt;
&lt;li&gt;스파스 : 교환법칙 성립, 겹쳐도 괜찮음 ( f(a,b,c) == f(f(a,b), f(b,c)) )&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1610643643176&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct SegTree {
    ll seg[MAX*4];
    ll (*func)(ll a, ll b), fail;
    ll init(vector&amp;lt;ll&amp;gt; &amp;amp;a, int no, int nl, int nr) {
        if(nl == nr) return seg[no] = a[nl];
        int mid = (nl + nr)/2;
        return seg[no] = func(init(a,no*2,nl,mid), init(a,no*2+1,mid+1,nr));
    }
    ll query(int l, int r, int no, int nl, int nr){
        if(r &amp;lt; nl || nr &amp;lt; l) return fail;
        if(l &amp;lt;= nl &amp;amp;&amp;amp; nr &amp;lt;=r) return seg[no];
        int mid = (nl + nr)/2;
        return func(query(l, r, no*2, nl, mid), query(l, r, no*2+1, mid+1, nr));
    }
    ll update(int i, ll v, int no, int nl, int nr) {
        if(i&amp;lt;nl || nr&amp;lt;i) return seg[no];
        if(nl == nr) return seg[no] = v; // += v;
        int mid = (nl + nr)/2;
        return seg[no] = func(update(i,v,no*2,nl,mid), update(i,v,no*2+1,mid+1,nr));
    }
} SEG;


// = main ========================

	SEG.func = [](ll a, ll b) {
		return (ll)(a + b);
	};
    SEG.fail = 0;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1614358994254&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct LazySeg {
	ll seg[MAX*4], lazy[MAX*4];
	void prop(int no, int nl, int nr) {
		if (lazy[no] != 0){
			seg[no] += (nr - nl +1)*lazy[no];	// FIX: [l,r] range apply
			if (nl != nr) {
				lazy[no*2] += lazy[no];
				lazy[no*2+1] += lazy[no];
			}
			lazy[no] = 0;
		}
	}
    ll init(vector&amp;lt;ll&amp;gt; &amp;amp;a, int no, int nl, int nr) {
        if (nl == nr) return seg[no] = a[nl];
        int mid = (nl + nr)/2;
        return seg[no] = init(a,no*2,nl,mid) + init(a,no*2+1,mid+1,nr);	// FIX: func
    }
	ll update(int l, int r, ll v, int no, int nl, int nr) {
		prop(no, nl, nr);
		if (r&amp;lt;nl || nr&amp;lt;l) return seg[no];
		if (l &amp;lt;= nl &amp;amp;&amp;amp; nr &amp;lt;= r) {
			lazy[no] = v;	// FIX: lazy apply 
			prop(no, nl, nr);
			return seg[no];
		}
		int mid = (nl+nr)/2;
		return seg[no] = update(l,r,v,no*2,nl,mid) + update(l,r,v,no*2+1,mid+1,nr);	// FIX: func
	}
	ll query (int l, int r, int no, int nl, int nr) {
		prop(no, nl, nr);
		if (r&amp;lt;nl || nr&amp;lt;l) return 0;
		if (l &amp;lt;= nl &amp;amp;&amp;amp; nr &amp;lt;= r) return seg[no];
		int mid = (nl + nr)/2;
		return query(l,r,no*2,nl,mid) + query(l,r,no*2+1,mid+1,nr);	// FIX: func
	}
} LS;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1612099525518&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct GoldSeg {
    static ll safe_add (const ll&amp;amp; a, const ll&amp;amp; b) {
        if (a &amp;gt; -LINF &amp;amp;&amp;amp; b &amp;gt; -LINF) return a+b;
        if (a &amp;gt; -LINF) return a;
        if (b &amp;gt; -LINF) return b;
        return -LINF;
    }
    struct Node {
        ll lval = -LINF, rval = -LINF, val = -LINF, all = 0;
        Node operator+ (const Node&amp;amp; n) const { return {safe_add(lval,n.lval), safe_add(rval,n.rval), safe_add(val,n.val), safe_add(all,n.all)}; }
    } seg[MAX*4];
    Node func(Node a, Node b) {
        return {
                max({a.lval, safe_add(a.all,b.lval)}),
                max({safe_add(a.rval,b.all), b.rval}),
                max({a.val, b.val, safe_add(a.rval,b.lval)}),
                max({safe_add(a.all,b.all)})
        };
    }
    Node init(vector&amp;lt;Node&amp;gt; &amp;amp;a, int no, int nl, int nr) {
        if(nl == nr) return seg[no] = a[nl];
        int mid = (nl + nr)/2;
        return seg[no] = func(init(a,no*2,nl,mid), init(a,no*2+1,mid+1,nr));
    }
    Node query(int l, int r, int no, int nl, int nr){
        if(r &amp;lt; nl || nr &amp;lt; l) return Node();
        if(l &amp;lt;= nl &amp;amp;&amp;amp; nr &amp;lt;= r) return seg[no];
        int mid = (nl + nr)/2;
        return func(query(l, r, no*2, nl, mid), query(l, r, no*2+1, mid+1, nr));
    }
    Node update(int i, Node v, int no, int nl, int nr) {
        if (i &amp;lt; nl || nr &amp;lt; i) return seg[no];
        if (nl == nr) return seg[no] = seg[no]+v; // = v
        int mid = (nl + nr) / 2;
        return seg[no] = func(update(i, v, no * 2, nl, mid), update(i, v, no * 2 + 1, mid + 1, nr));
    }
} GSEG;

vector&amp;lt;GoldSeg::Node&amp;gt; nodes;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1626857853485&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct RectSeg {	// 직사각형들의 넓이를 관리하는 웰논 세그 (boj.kr/3392)
    ll cnt[MAX * 4], rng[MAX * 4], diff[MAX * 4];
    ll init(vector&amp;lt;ll&amp;gt; &amp;amp;zip, int no, int nl, int nr) {    // 압축한 좌표를 토대로, 노드 사이 실제 차이를 계산
        if (nl == nr) return diff[no] = zip[nl] - zip[nl-1];    // 0~1 --&amp;gt; 1
        int mid = (nl + nr)/2;
        return diff[no] = init(zip,no*2,nl,mid) + init(zip,no*2+1,mid+1,nr);
    }
    void prop(int no, int nl, int nr) {
        if (cnt[no] &amp;gt; 0) rng[no] = diff[no]; // colored: return self's width
        else {  // uncolored: just merge childs
            if (nl != nr) rng[no] = rng[no*2] + rng[no*2+1];
            else rng[no] = 0;
        }
    }
    ll query(int l, int r, int no, int nl, int nr) {
        if (r &amp;lt; nl || nr &amp;lt; l) return 0ll;
        if (l &amp;lt;= nl &amp;amp;&amp;amp; nr &amp;lt;= r) return rng[no];
        int mid = (nl+nr)/2;
        return query(l, r, no*2, nl, mid) + query(l, r, no*2+1, mid+1, nr);
    }
    void update(int l, int r, int v, int no, int nl, int nr) {
        if (r &amp;lt; nl || nr &amp;lt; l) return;
        if (l &amp;lt;= nl &amp;amp;&amp;amp; nr &amp;lt;= r) {
            cnt[no] += v;
            prop(no, nl, nr); return;
        }
        int mid = (nl+nr)/2;
        update(l, r, v, no*2, nl, mid); update(l, r, v, no*2+1, mid+1, nr);
        prop(no, nl, nr);
    }
} RS;

// ========================
RS.init(yzip, 1, 1, N-1);
RS.query(1, N-1, 1, 1, N-1);
RS.update(r.xx+1, r.yy, (r.flag?-1:+1), 1, 1, N-1);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1614358806212&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct SparseTable {
    ll arr[MAX][30], lg2[MAX];  // 30=lg2(1e9), 20=lg2(1e6)
    ll (*func)(ll a, ll b);     // f(a,b,c) == f(f(a,b), f(b,c))

    void init(int n) {
        for (int j = 1; (1ull &amp;lt;&amp;lt; j) &amp;lt; n; ++j) {
            lg2[(1ull &amp;lt;&amp;lt; j)] = j;
            for (int i = 0; i + (1ull &amp;lt;&amp;lt; (j-1)) &amp;lt; n; ++i) {
                arr[i][j] = func(arr[i][j-1], arr[i + (1ull &amp;lt;&amp;lt; (j-1))][j-1]);
            }
        }
        for (int i = 0; i &amp;lt;= n; ++i) {
            if (!lg2[i]) lg2[i] = lg2[i-1];
        }
    }
    ll query(int l, int r) {
        ll lefts = r - (1ull &amp;lt;&amp;lt; lg2[r - l + 1]) + 1;
        return func(arr[l][lg2[r - l + 1]], arr[lefts][lg2[r - l + 1]]);
    }
};&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/정리글</category>
      <category>SegmentTree</category>
      <category>세그</category>
      <category>세그먼트트리</category>
      <category>세그트리</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/13</guid>
      <comments>https://kimhwon.tistory.com/13#entry13comment</comments>
      <pubDate>Fri, 15 Jan 2021 02:02:06 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #694 (Div. 2)</title>
      <link>https://kimhwon.tistory.com/12</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;107&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwKRXu/btqS1VFLqfa/p1sZJhgNoCqej5skNaQVd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwKRXu/btqS1VFLqfa/p1sZJhgNoCqej5skNaQVd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwKRXu/btqS1VFLqfa/p1sZJhgNoCqej5skNaQVd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwKRXu%2FbtqS1VFLqfa%2Fp1sZJhgNoCqej5skNaQVd0%2Fimg.png&quot; data-origin-width=&quot;1472&quot; data-origin-height=&quot;107&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;A. Strange Partition&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;수열과 정수 x가 주어진다. 수열의 원소들을 적절히 서로 합쳐서, 각 원소를 x로 나누고 올림한 값들의 총합이 최소가 되거나 최대가 되게 해야하는 문제.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;어떤 수를 x로 나누고 올림했을 때 값이 바뀌려면 x로 나눈 나머지가 있어야 한다. 잘 생각해 보면 두 원소가 따로 있을 때는 x의 배수가 아니다가 합치면 x의 배수가 되어버릴 수 있다. 그러면 합치기 전에는 각각 올림해서 값이 증가할 텐데, 합친 뒤에는 나머지가 없기에 올림을 해도 값이 증가하지 않는다. 따라서 모든 원소를 다 합쳐버린 상태가 최소가 되는 상태이고, 전혀 합치지 않은 상태가 최대가 되는 상태이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;B. Strange List&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;수열과 정수 x가 주어진다. 수열을 하나씩 순회하면서 지금 보는 원소가 x로 나누어지면, 그 몫을 x개 만큼 수열 맨 뒤에 추가한다. 만약 x로 나누어지지 않으면 끝낸다. 끝난 시점에서 수열의 총 합이 얼마인지 알아내는 문제.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;일단 원소를 나눈 몫을 x개 추가하므로, 새로 추가되는 수들의 합은 원래 원소의 값과 같다. 즉, a_i/x를 x개 추가하므로 a_i/x * x = a_i 인 것이다. 새로 수열에 추가되는 연산이 최대 몇 번 있는지 생각해보면, 어떤 원소가 같은 수로 계속 나누어 떨어져야 한다. 입력되는 범위(&amp;lt;=10^9) 내에서 이런 경우는 2^29을 2로 나누는 경우일 것이다. 최대 29번 나누어지므로 각 원소당 29번 이내에 반복이 끝난다는 것을 알 수 있다. 따라서 그냥 주어진 수열에 끝나는 조건이 나올 때까지 x로 나눠나가다 보면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;C. Strange Birthday Party&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수열 k와 정렬된 수열 c가 주어진다. k의 모든 원소에 대하여 1. &lt;span data-mathml=&quot;&amp;lt;math xmlns=&amp;quot;http://www.w3.org/1998/Math/MathML&amp;quot;&amp;gt;&amp;lt;mi&amp;gt;j&amp;lt;/mi&amp;gt;&amp;lt;mo&amp;gt;&amp;amp;#x2264;&amp;lt;/mo&amp;gt;&amp;lt;msub&amp;gt;&amp;lt;mi&amp;gt;k&amp;lt;/mi&amp;gt;&amp;lt;mi&amp;gt;i&amp;lt;/mi&amp;gt;&amp;lt;/msub&amp;gt;&amp;lt;/math&amp;gt;&quot;&gt;&lt;span&gt;j&amp;lt;=k_i 를 만족하는&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-mathml=&quot;&amp;lt;math xmlns=&amp;quot;http://www.w3.org/1998/Math/MathML&amp;quot;&amp;gt;&amp;lt;msub&amp;gt;&amp;lt;mi&amp;gt;c&amp;lt;/mi&amp;gt;&amp;lt;mi&amp;gt;j&amp;lt;/mi&amp;gt;&amp;lt;/msub&amp;gt;&amp;lt;/math&amp;gt;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;c_&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;j 를 더하거나 2. c_{k_i}를 더할 수 있다. 단, 1번 방법에서는 c의 원소를 한 번씩만 사용할 수 있다. 합을 최소화하는 문제.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;c가 정렬되어 있으므로 k_i가 클 수록&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;2번 방법을 선택했을 때의 페널티가 커진다. 따라서 k_i가 클 수록 가능한 1번 방법을 선택하는 것이 최적이라고 생각해 볼 수 있다. k를 내림차순으로 정렬하고, &lt;span style=&quot;color: #333333;&quot;&gt;c_{k_i}의 합을 관리한다. &lt;/span&gt;가장 큰 k_i부터 1번 방법으로 가장 작은 c_j를 선택해나가 보자. 적절히 합을 관리한다면 모든 경우를 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;D.&amp;nbsp;&lt;/span&gt;Strange Definition (업솔빙)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;두 수 x와 y에 대하여 l&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;m&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;) / &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;g&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;) 가 완전제곱수면 '인접'했다고 정의해보자. 수열이 하나 주어지고 1초가 지날 때마다 서로 '인접'한 원소들이 서로 곱해진다. 쿼리로 시간이 주어졌을 때 각 쿼리에서 '인접'한 원소가 가장 많은 수를 알아내는 문제.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;서로 '인접'한 원소들을 관리해주는 것이 키포인트이다. 어떤 원소를 소인수분해하면 a^3 * b^4 * c^5 이런 식으로 나올텐데 홀수 차수인 값만 남기고 무시해도 된다. 즉, a * c 이렇게 두 인자만 남게 된다. 왜냐하면 &lt;span&gt;제곱수는 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;l&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;m&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;) /&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;g&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;d&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;한 후에 남아있어도 &lt;span&gt;인접한 것은 자명하기 때문이다. 0초에서 1초로 넘어갈 때는 서로 곱해질 텐데, 이 경우도 마찬가지로 짝수차수가 만들어지면 무시하고 홀수 차수인 값만 남길 수 있다. 이렇게 되면 이전 상태에서 그대로 있거나 1로 바뀌게 된다. 1초에서 2초로 넘어갈 때는 이미 1초로 넘어올 때 정리가 되었기 때문에 '인접'한 관계가 변하지 않는다. 즉, 0초일 때 한번, 1초일 때 한번만 '인접'한 원소들의 수를 세어주면 된다. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/12</guid>
      <comments>https://kimhwon.tistory.com/12#entry12comment</comments>
      <pubDate>Sat, 9 Jan 2021 14:56:47 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #693 (Div. 3)</title>
      <link>https://kimhwon.tistory.com/11</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1464&quot; data-origin-height=&quot;111&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beOPaT/btqSKMVZ4VB/KuJYcPPTLsc2fku1nBbUVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beOPaT/btqSKMVZ4VB/KuJYcPPTLsc2fku1nBbUVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beOPaT/btqSKMVZ4VB/KuJYcPPTLsc2fku1nBbUVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeOPaT%2FbtqSKMVZ4VB%2FKuJYcPPTLsc2fku1nBbUVk%2Fimg.png&quot; data-origin-width=&quot;1464&quot; data-origin-height=&quot;111&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;딥3라 그런지 &lt;span style=&quot;color: #333333;&quot;&gt;E도 꽤 풀렸는데&lt;/span&gt; E번을 못 푼게 좀 아쉬웠다. 다행이 레이팅은 안떨어짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;A. Cards for Friends&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;w*h 크기의 카드를 n개 조각으로 자를 수 있는지 확인하는 문제. 자를 조건은 자르려는 변이 짝수여야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;가능한 최대로 자르고 그 조각의 수를 n과 비교하면 된다. 최대한 자른 횟수는 변이 나누어 떨어지는 가장 큰 2^k이다. (절반씩 자르므로)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;별거 아닌데 구현이 말려서 늦었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;B.&amp;nbsp;&lt;span&gt;Fair Division&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;1g짜리 사탕과 2g짜리 사탕이 주어질 때 두 종류의 사탕을 같은 무게로 분할 할 수 있는지 알아내는 문제.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;2g짜리를 먼저 최대한 공평하게 나누고, 남은 차이를 1g짜리로 채울 수 있는지 확인하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;&lt;span&gt;C. Long Jumps&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span&gt;수열이 주어지고 임의의 위치에서 시작한다. 현재 원소의 값만큼 점수를 더하고 원소의 값 만큼 오른쪽으로 이동한다. 수열 바깥으로 나갈 때까지 반복할 때, 최대 점수를 찾는 문제.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;&lt;span&gt;임의의 위치 i에 대하여, 이전에 어떤 방법으로든 i에 도달할 수 있었다면 그 점수에 이어서 누적하는 것이 최적이다. 반대로 이전에 어떤 방법으로든 i에 도달 할 수 없었다면 i가 시작점이 되어야 한다. a_1부터 반복문을 돌면서 위 논리를 적용하면서 점수의 최대값을 관리해주면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;D.&amp;nbsp;&lt;span&gt;Even-Odd Game&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수열이 주어지고 두 사람이 번갈아 가며 원소를 선택하고 없앤다. 한 사람은 짝수를 선택하면 그 원소만큼 점수를 누적하고, 다른 사람은 홀수를 선택하면 그 원소만큼 점수를 누적한다. 점수를 못 받더라도 원소를 선택하고 없앨 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;확신이 없어서 E번 보다가 그냥 냈더니 맞았다. 게임 쪽은 많이 부족한 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;직관적으로 가장 큰 원소를 고르는 것이 최적임은 당연하다. 한 사람이 할 수 있는 행동은 1. 자기가 점수를 얻도록 선택하거나 2. 상대방이 점수를 못 얻도록 선택하는 두 가지가 있다. 내가 1번 선택을 아무리 잘 했더라도 상대가 큰 점수를 얻어버리면 지게 된다. 따라서 (내가 얻는 이득)과 (상대가 얻을 이득)을 비교해서 더 큰 쪽을 선택하거나 방해하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;E.&amp;nbsp;Correct Placement (업솔빙)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;pair들이 주어지고, 한 pair 앞에 다른 pair가 존재할 수 있는지 확인하는 문제다. (x_i, y_i)와 (x_j, y_j)에 대하여 x_i &amp;lt; x_j &amp;amp;&amp;amp; y_i &amp;lt; y_j 이거나 x_i &amp;lt; y_j &amp;amp;&amp;amp; y_i &amp;lt; x_j 를 만족하면 (x_i, y_i)가 (x_j, y_j)의 앞에 존재할 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;모든 pair들을 x좌표로 정렬을 한 뒤, 순회하면서 각 x좌표에 대한 y좌표의 prefix min 값을 구한다. 예를 들어 (1,5) (1,8) (2,3) (2,7) (4,6) 이 있다면 pmin[1]=5, pmin[2]=3, pmin[4]=3 이런 식으로 x좌표 값을 알 때 가능한 가장 작은 y값을 저장하고, 그 위치도 관리한다. x값과 y값을 바꿀 수 있으므로 (x_i, y_i)에 대하여 벡터에 (x_i, y_i)와 (y_i, x_i)를 모두 벡터에 집어 넣고 순회하면서, 이전에 정렬한 pair들에서 이분 탐색으로 x좌표에 대한 조건이 맞는 지점을 찾는다. 그리고 prefix min 값을 보고 해당 x좌표값에서 y좌표에 대한 조건도 만족이 되는지 확인을 해주면 된다.&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/11</guid>
      <comments>https://kimhwon.tistory.com/11#entry11comment</comments>
      <pubDate>Sat, 9 Jan 2021 14:15:27 +0900</pubDate>
    </item>
    <item>
      <title>정수론 잡지식</title>
      <link>https://kimhwon.tistory.com/10</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;인버스 모듈러&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ A^{-1} \equiv A^{M-2} \pmod{M} $&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A^{M-2} 는 분할정복으로 nlogn 으로 구현 가능 (pow는 오버플로 주의)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 이항계수도 해결 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$ _{n}\mathrm{C}_{r} \bmod M = \frac{ n! }{ (n-r)! \, r! } \bmod M = ( n! \bmod M ) ( (n-r)! \, r! )^{-1} \bmod M = ( n! \bmod M ) ( (n-r)! \, r! )^{M-2} \bmod M $&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;이항계수 코드&lt;/h4&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1631325202142&quot; class=&quot;c++ arduino&quot; data-ke-language=&quot;c++&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct Combination {
    ll fact[MAX];
    ll safe_mul(ll a, ll b) { return ((a%MOD) * (b%MOD)) % MOD; }
    void init(int n=MAX) {
        fact[0] = 1;
        for (int i = 1; i &amp;lt; n; ++i) fact[i] = safe_mul(fact[i-1], i);
    }
    ll fast_pow(ll n, ll e) {
        ll ret = 1;
        while (e &amp;gt; 0) {
            if (e % 2) ret = safe_mul(n, ret);
            e /= 2;
            n = safe_mul(n, n);
        }
        return ret;
    }
    ll comb(ll n, ll k) {
        return safe_mul(
                fact[n],
                fast_pow(safe_mul(fact[n-k], fact[k]), MOD-2)
                );
    }
} CM;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;소수 개수&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1e5 이하 : 9 592&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1e7 이하 : 664 579&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;1e9 이하 : 50 847 534&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;약수&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개수 : O( N^{1/3} )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총합 : O( N loglog N )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;O(sqN) 안에 나이브하게 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;소인수분해&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kimhwon.tistory.com/9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;kimhwon.tistory.com/9&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1e7 이하 소인수 갯수는 7개&amp;nbsp; (1e8 이상부터는 체 돌리는데도 3초 넘김)&lt;/p&gt;</description>
      <category>알고리즘/정리글</category>
      <category>정수론</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/10</guid>
      <comments>https://kimhwon.tistory.com/10#entry10comment</comments>
      <pubDate>Wed, 6 Jan 2021 02:15:09 +0900</pubDate>
    </item>
    <item>
      <title>에라토스테네스의 체 (소인수분해)</title>
      <link>https://kimhwon.tistory.com/9</link>
      <description>&lt;pre id=&quot;code_1609864665407&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct Sieve {
    int isPrime[MAX+2];	// 소수거나 0, 1이면 -1,  합성수면 가장 작은 소인수
    void find_prime(){
        memset(isPrime, -1, sizeof(isPrime));
        int sqMAX = sqrt(MAX)+1;
        for(long long i=2; i&amp;lt;=sqMAX; ++i)
            if(isPrime[i] == -1)
                for(long long j=i*i; j&amp;lt;=MAX; j+=i)
                    if(isPrime[j] == -1)
                        isPrime[j] = i;
    }
    void print_factor(int n, vector&amp;lt;pii&amp;gt;&amp;amp; elem){	// 소인수 {e, k}
        elem.emplace_back(0, 0);
        while(isPrime[n] != -1){
            if (elem.back().xx == isPrime[n]) {
                ++elem.back().yy;
            } else {
                elem.emplace_back(isPrime[n], 1);
            }
            //cout &amp;lt;&amp;lt; isPrime[n] &amp;lt;&amp;lt; ' ';
            n /= isPrime[n];
        }
        //cout &amp;lt;&amp;lt; n;
        if (elem.back().xx == n) {
            ++elem.back().yy;
        } else {
            elem.emplace_back(n, 1);
        }
        elem.erase(elem.begin());
    }
} SV;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/정리글</category>
      <category>sieve</category>
      <category>소수</category>
      <category>소인수분해</category>
      <category>에라토스테네스의 체</category>
      <category>정수론</category>
      <category>체</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/9</guid>
      <comments>https://kimhwon.tistory.com/9#entry9comment</comments>
      <pubDate>Wed, 6 Jan 2021 01:40:24 +0900</pubDate>
    </item>
    <item>
      <title>Codeforces Round #692 (Div. 2, based on Technocup 2021 Elimination Round 3)</title>
      <link>https://kimhwon.tistory.com/8</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kNwKn/btqSbawsgeN/EaG0WXd8pCcHLwBxIgKY61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kNwKn/btqSbawsgeN/EaG0WXd8pCcHLwBxIgKY61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kNwKn/btqSbawsgeN/EaG0WXd8pCcHLwBxIgKY61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkNwKn%2FbtqSbawsgeN%2FEaG0WXd8pCcHLwBxIgKY61%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어제 낮에 쳤던 버추얼 라운드. 어려웠다&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A. &lt;span&gt;In-game Chat&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;문자열의 끝에서부터 연속된 )의 개수가 전체 길이의 절반을 초과하는지 찾는 문제.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;반복문을 뒤에서부터 돌면서 찾으면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;B. &lt;span&gt;Fair Numbers&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;정수의 각 자리의 수들로 모두 나누어지는 정수를 찾아야 한다. 주어진 정수 이상의 수들 중 조건을 만족하는 가장 작은 수를 찾는 문제.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;처음에 직접 정수를 만드는 규칙을 찾으려고 해서 많이 헤맸다. 울프람알파에 주어진 테케를 이것저것 넣다 보니까 lcm(1,2,3,4,5,6,7,8,9)=2520라는 사실을 찾아냈다. 이는 어떤 정수가 어떤 수로 이루어져 있든지, 2520 내에서 최소 한번의 약수가 존재한다는 뜻이다. 주어진 정수에서부터 brute-force로 1씩 증가시키면서 조건을 만족하는 가장 작은 수를 찾았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;C. &lt;span&gt;Peaceful Rooks (업솔빙)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;체스판의 크기와 룩 &lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_8_1&quot; id=&quot;footnote_link_8_1&quot; onmouseover=&quot;tistoryFootnote.show(this, 8, 1)&quot; onmouseout=&quot;tistoryFootnote.hide(8, 1)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;1&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt; 이 주어지고 이 룩들이 서로를 공격하는 위치에 정지하지 않으면서 전부 주대각선 &lt;span style=&quot;color: #333333;&quot;&gt;&lt;sup class=&quot;footnote&quot;&gt;&lt;a href=&quot;#footnote_8_2&quot; id=&quot;footnote_link_8_2&quot; onmouseover=&quot;tistoryFootnote.show(this, 8, 2)&quot; onmouseout=&quot;tistoryFootnote.hide(8, 2)&quot; style=&quot;color:#f9650d; font-family: Verdana, Sans-serif; display: inline;&quot;&gt;&lt;span style=&quot;display: none;&quot;&gt;[각주:&lt;/span&gt;2&lt;span style=&quot;display: none;&quot;&gt;]&lt;/span&gt;&lt;/a&gt;&lt;/sup&gt;&lt;/span&gt; 으로 몇 번만에 이동시킬 수 있는지 알아내는 문제.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전혀 감을 잡지 못했다. &lt;span style=&quot;color: #333333;&quot;&gt;에디토리얼&lt;/span&gt;을 보고 나름대로 이해하고 정리해보았다. 직관과 뇌피셜로 범벅이 된 해설이므로... 에디토리얼을 직접 보기 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 한 개의 룩이 어떻게 움직이는지 생각해보자. 룩은 가로 또는 세로로 무한정 움직일 수 있으므로 원하는 위치로 움직이기 위해 최대 2번 움직인다. 따라서 각 룩에 대해서 0~2번 사이에 모두 주대각선 위로 움직일 수 있다. 초기 위치가 이미 주대각선 위인 경우, 0번 움직인다. 문제에서 최소한으로 이동해야 한다고 했으니, 초기 위치(x_i, y_i)가 (x_i, x_i) 또는 (y_i, y_i)로 1번만에 이동하는 경우가 최적일 것이다. 그런데 이런 방식으로 이동하지 못 하는 경우도 있다. 이 두 위치와 이미 다른 룩의 위치가 일직선에 있는 경우 즉, (x_i, y_j), (y_i, y_j), (x_j, x_i), (x_j, y_i) 에 있는 경우다. 이렇게 다른 룩에 &quot;점유된&quot; 상태를 Disjoint-set으로 표현할 수 있다. 점유된 좌표 &lt;span style=&quot;color: #333333;&quot;&gt;(x_i, y_i)를&lt;/span&gt; merge하자. 만약 (x_j, y_j)를 이동하려고 할 때, x_j와 y_j가 같은 집합 내에 있다면 둘 중 최소 하나의 좌표는 이미 &quot;점유&quot;되어 있으므로 2번 이동하여 다른 주대각선 위치로 이동해야 한다. 이러한 방법으로 각 룩에 대하여 0번, 1번, 2번만에 주대각선에 도착하게 만들 수 있다.&lt;/p&gt;
&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol class=&quot;footnotes&quot;&gt;
    &lt;li id=&quot;footnote_8_1&quot;&gt; 체스말 Rook  &lt;a href=&quot;#footnote_link_8_1&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
    &lt;li id=&quot;footnote_8_2&quot;&gt; 행렬[i][j] 에서 i=j인 위치  &lt;a href=&quot;#footnote_link_8_2&quot;&gt;[본문으로]&lt;/a&gt;&lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</description>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/8</guid>
      <comments>https://kimhwon.tistory.com/8#entry8comment</comments>
      <pubDate>Tue, 5 Jan 2021 22:07:41 +0900</pubDate>
    </item>
    <item>
      <title>Good Bye 2020</title>
      <link>https://kimhwon.tistory.com/7</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1473&quot; data-origin-height=&quot;142&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c67YVl/btqRVqUhdiS/HJCo3zT6qmyqQ4prLv1NF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c67YVl/btqRVqUhdiS/HJCo3zT6qmyqQ4prLv1NF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c67YVl/btqRVqUhdiS/HJCo3zT6qmyqQ4prLv1NF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc67YVl%2FbtqRVqUhdiS%2FHJCo3zT6qmyqQ4prLv1NF1%2Fimg.png&quot; data-origin-width=&quot;1473&quot; data-origin-height=&quot;142&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;낮에 버추얼 한번 쳐서 딱히 칠 생각 없었는데 Global round가 레이팅 올리기 쉽다고 해서 호다닥 신청했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A.&amp;nbsp;Bovine&amp;nbsp;Dilemma&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;삼각형의 높이가 정해져있고 밑변으로 삼을 수 있는 점들이 주어진다. 이 점들 중 2개를 적절히 골라 밑변으로 삼았을 때, 서로 다른 삼각형의 넒이의 개수를 구하는 문제.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;n이 50이라 그냥 n^2 반복문 돌려서 넓이를 전부 구하고 unique로 중복제거했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;B.&amp;nbsp;Last&amp;nbsp;minute&amp;nbsp;enhancements&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;단조 증가하는 수열이 주어지고, 임의의 원소를 +1 할 수 있다. 가능한 다양한 숫자가 나오게 만드는 문제.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;증가할 수는 있지만 감소할 수는 없으므로, 내가 +1을 하면 다음 원소랑 겹친다면 굳이 할 필요가 없다. 즉, 뒤에서부터 돌면서 (현재 값)+1 &amp;lt; (오른쪽 값) 이면 +1을 해주고 아니면 패스하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;C.&amp;nbsp;&lt;span&gt;Canine poetry&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;문자열이 주어지고 이 문자열의 부분 문자열 중, 길이가 1 초과인 팰린드롬이 없도록 해야 한다. 고쳐야 하는 글자의 최소 수를 구하는 문제.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;아이디어가 떠오르지 않아서 넘기고 D풀다가 1시간 남기고 다시 돌아와서 겨우 냈다. 내 풀이는 Manacher 알고리즘으로 팰린드롬들을 다 찾은 다음, 찾은 팰린드롬의 중심의 바로 왼쪽 또는 오른쪽을 끊어내버린다. 팰린드롬의 길이가 3 이상일 경우, 끝에 있는 문자를 바꾸면 더 짧아질 뿐 팰린드롬이 사라지지 않으므로 중심에서 가장 가까운 문자를 지워야 한다. (ex. &lt;u&gt;&lt;span style=&quot;color: #000000;&quot;&gt;abcba&lt;/span&gt;&lt;/u&gt; -&amp;gt; &lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;a&lt;/span&gt;&lt;u&gt;bcb&lt;/u&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;x&lt;span style=&quot;color: #333333;&quot;&gt;,&lt;span&gt; &lt;u&gt;&lt;span style=&quot;color: #000000;&quot;&gt;abcba&lt;/span&gt;&lt;/u&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;-&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;abc&lt;span style=&quot;color: #ee2323;&quot;&gt;x&lt;/span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) 중심의 왼쪽과 오른쪽을 선택하는 문제는 '그리디하게 라인스윕하면서 선분 끊기' 방법이 될거라는 직감으로 풀었다. 왼쪽 위치, 오른쪽 위치를 pair에 넣고 순회하면서 끝점을 계속 잘라갔다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;내 풀이는 사실 논리상 결국 맞긴 한데, 돌고 돌아서 맞은 상황이고 쉬운 해설(from. Green55)은 다음과 같다. 1. &lt;span&gt;홀수 길이 팰린드롬은 항상 중간에 길이가 3인 팰린드롬을 갖고 있고, &lt;span&gt;짝수 길이는 2인 팰린드롬을 갖고 있기 때문에 &lt;span&gt;길이가 2,3인 팰린드롬만 없애주면 된다. 2. &lt;span&gt;어떤 문자를 바꿀 때 그냥 더미 문자 ?로 바꾸고 &lt;span&gt;?가 포함되는 문자열은 절대 팰린드롬이 아니라고 생각해도 된다. 나중에 ?를 적절한 문자로 채울 수 있기 때문이다.(직관적으로)&lt;/span&gt;&lt;/span&gt; 3-1. 따라서 dp&lt;span&gt;[n][2][2] 잡고 &lt;span&gt;현재 위치랑 &lt;/span&gt;&lt;span&gt;이전 문자, 이전의 이전 문자를 ?로 바꿨는지만 기억하면 된다. 3-2. 또는 그리디하게 &lt;span&gt;i를 기준으로 a[i] == a[i+1]이면 i+1을 ?로 바꾸고 &lt;span&gt;a[i] == a[i+2]면 i+2를 ?로 바꾼다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;D. &lt;span&gt;13th Labour of Heracles&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;트리가 주어지고 이 트리의 간선을 k개의 색깔로 칠했을 때, 같은 색 간선끼리 서브트리를 만든다. 각 서브트리에 속하는 정점의 weight의 합들의 합이 최대가 되도록 계산하는 문제. 1부터 n-1까지 모든 k에 대해서 다 구해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;서브트리가 끊어져 있으면 조각들 중 최대값만 사용하므로 당연히 서로 인접한 간선끼리 색칠해야한다. 잘 생각해보면 색깔이 달라지는 경계에 있는 정점은 인접한 간선의 색만큼 중복해서 세진다. (ex. &lt;span style=&quot;color: #ee2323;&quot;&gt;---&lt;/span&gt;a&lt;span style=&quot;color: #ee2323;&quot;&gt;---&lt;/span&gt; -&amp;gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;---&lt;/span&gt;a&lt;span style=&quot;color: #006dd7;&quot;&gt;---&lt;/span&gt; 이면 a가 빨간 서브트리와 파란 서브트리에서 두 번 세진다.) 즉, 한 정점에 연결된 간선들이 같은 색으로 다 칠해져 있다가, 한 간선의 색이 바뀌면 전체 합이 그 정점의 weight만큼 증가한다. 처음 k=1일 때는 단순히 weight의 총합이 답이다. 여기서 색이 하나씩 추가될 때마다 차수가 1 이상인 정점 중 weight가 가장 큰 정점부터 더해나가고, 더한 정점의 차수를 1 감소시키면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;E.&amp;nbsp;Apollo versus Pan (실패)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;임의의 양의 정수로 이루어진 수열에서 아래 수식의 답을 계산하는 문제&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;80&quot; width=&quot;243&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Iyy21/btqROdVLJk1/FNn58I6QyFzB7aQ9Twk1vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Iyy21/btqROdVLJk1/FNn58I6QyFzB7aQ9Twk1vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Iyy21/btqROdVLJk1/FNn58I6QyFzB7aQ9Twk1vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIyy21%2FbtqROdVLJk1%2FFNn58I6QyFzB7aQ9Twk1vk%2Fimg.png&quot; data-origin-width=&quot;286&quot; data-origin-height=&quot;80&quot; width=&quot;243&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;왠지 FFT일 것 같아서 &lt;a href=&quot;https://codeforces.com/blog/entry/55271&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;검색을 해 보니 and 또는 or 연산에 대해서도 빠르게 연산할 수 있다&lt;/a&gt;고 해서 해당 포스트를 이해해보려고 시도해보았으나 결국 시간만 날리고 실패했다. Editorial 보니까 FFT도 아니고 읽어봐도 잘 이해가 안가서 천천히 시간을 두고 다시 업솔해보려고 한다. 다음부터는 검색하지 말고 잘 모르겠으면 건들지도 말자.&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/7</guid>
      <comments>https://kimhwon.tistory.com/7#entry7comment</comments>
      <pubDate>Thu, 31 Dec 2020 05:25:18 +0900</pubDate>
    </item>
    <item>
      <title>Educational Codeforces Round 101 (Rated for Div. 2)</title>
      <link>https://kimhwon.tistory.com/6</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1471&quot; data-origin-height=&quot;137&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjoL7h/btqRI7mOFLC/hfiwmFxtltBSIXhjtdg2U0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjoL7h/btqRI7mOFLC/hfiwmFxtltBSIXhjtdg2U0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjoL7h/btqRI7mOFLC/hfiwmFxtltBSIXhjtdg2U0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjoL7h%2FbtqRI7mOFLC%2FhfiwmFxtltBSIXhjtdg2U0%2Fimg.png&quot; data-origin-width=&quot;1471&quot; data-origin-height=&quot;137&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;A. &lt;span&gt;Regular Bracket Sequence&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;( , ) , ?가 포함된 괄호문자열을 주고 ?에 적절한 괄호를 넣어서 온전한 괄호문자열을 만들 수 있는지 출력하는 문제.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;문제의 조건에서 &lt;b&gt;&lt;span&gt;There is exactly one character&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and exactly one character&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;in this sequence. 라는 문장을 제대로 이해하지 못해서 헤맸다. 해석하면 주어진 문자열에 (가 한 개, )가 한 개, 나머지는 ?이다. 라는 뜻인데 이 조건 없이 그냥 풀다가 구현 말리고 결국 뇌절해서 DP로 풀었음.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;정해로는 1. 길이가 짝수고, 2. )로 시작하지 않으면서 3. (로 끝나지 않는다. 3가지 조건을 만족하면 무조건 가능하다. 중간은 적당히 아무거나 채워 넣으면 되기 때문.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;B. &lt;span&gt;Red and Blue&lt;/span&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;빨간색으로 칠한 수열과 파란색으로 칠한 수열이 주어질 때, 두 수열의 순서를 바꾸지 않으면서 잘 배치해서 합친다. 합친 수열 a에서 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;f&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;max&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;&amp;hellip;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;⋯&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;a&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;m&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;) 에 대하여 f(a)의 최대값을 구하는 문제.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;이 문제도 뇌절와서 DP로 풀다가 틀리고 다시 풀었다. 순서를 바꾸지 않으므로, (빨간 수열에서 누적합의 최대) + (파란 수열에서 누적합의 최대) 가 답이다. 각 수열에서 누적합이 최대가 되는 지점까지만 잘 배치한다면 그 지점이 a의 최대값이 되기 때문. 예를 들어 &lt;span style=&quot;color: #ee2323;&quot;&gt;-1 4 5 2 -9 3&lt;span style=&quot;color: #006dd7;&quot;&gt; 3 9 0 -2 -5&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;이렇게 있다면 &lt;span style=&quot;color: #000000;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;-1 4 5 2 &lt;span style=&quot;color: #006dd7;&quot;&gt;3 9 0&lt;span style=&quot;color: #000000;&quot;&gt;)&lt;/span&gt; &lt;/span&gt;-9 3 &lt;span style=&quot;color: #006dd7;&quot;&gt;-2 -5&lt;span style=&quot;color: #000000;&quot;&gt; 이런 식으로 최대 지점을 앞에다 몰아놓으면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;C. Building a Fence&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;조건을 만족하면서 fence를 세울 수 있는지 알아내는 문제. fence는 이웃한 fence와 1칸 이상 겹쳐야 하고, 바닥에서 k-1칸 이상 떨어지면 안된다. 양 끝의 fence는 바닥에 붙어있어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;왼쪽 끝 fence를 고정시키고, 오른쪽으로 fence를 구성해나간다. 현재 위치에 대하여 조건을 만족하는 최대 fence 위치와 최소 fence 위치를 관리해주면 된다. 오른쪽 끝 fence가 이 영역 내에 있는지 확인하면 ok.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;D. Ceil Divisions (업솔빙)&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;1부터 n까지 수열에서 ax = ceil(ax / ay) 연산을 할 수 있다.(x != y) 잘 치환해서 수열에서 2가 하나, 나머지가 전부 1이 되게 바꾸는 문제. 단, 치환 횟수는 N+5번 이하여야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span&gt;2^(2^k) 가 키워드다. &lt;span style=&quot;color: #333333;&quot;&gt;2^(2^(i+1)) 는 &lt;span style=&quot;color: #333333;&quot;&gt;2^(2^i)로 나누면 &lt;span style=&quot;color: #333333;&quot;&gt;2^(2^i)가 나오므로 2번 만에 1로 만들 수 있다. (ex. 64, 256 -&amp;gt; 256/64=64, 64/64=1) 2부터 n미만의 모든 2^(2^k), n을 따로 관리한다. (2, 4, 16, 256, ... , n) 이들을 제외한 나머지 수는 전부 인접한 수와 나눠서 1로 만들어버리고, 남은 &lt;span style=&quot;color: #333333;&quot;&gt;2^(2^k)들을 이웃한 원소끼리 나눠서 2번만에 1로 만들어버리면 된다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>알고리즘/Codeforces</category>
      <category>CodeForces</category>
      <author>hwon233</author>
      <guid isPermaLink="true">https://kimhwon.tistory.com/6</guid>
      <comments>https://kimhwon.tistory.com/6#entry6comment</comments>
      <pubDate>Tue, 29 Dec 2020 03:00:35 +0900</pubDate>
    </item>
  </channel>
</rss>