{"componentChunkName":"component---src-templates-blog-post-js","path":"/Algorithm/BOJ-2042-Python/","result":{"data":{"site":{"siteMetadata":{"title":"hyesungoh","author":"hyesungoh","siteUrl":"https://www.hyesungoh.xyz","comment":{"disqusShortName":"","utterances":"hyesungoh/blog"},"sponsor":{"buyMeACoffeeId":""}}},"markdownRemark":{"id":"3251fe26-a9ae-51d6-9254-b5d65c83d4b0","excerpt":"n개의 수가 주어진 후 수열의 값을 변경, 해당 수열의 구간 합을 출력하는 문제. 세그먼트 트리 방식을 이용하여 풀었으며 입력되는 수들을 배열에 저장, 새로운 배열을 세그먼트 트리화하였다. init, sum, change 함수 모두 재귀적으로 호출하여 사용하였으며 중간 값 나누기 연산을 변수에 할당하여 작지만 연산을 줄여 풀었다. 자세한 풀이는 문제의 주석을 참고","html":"<p>n개의 수가 주어진 후 수열의 값을 변경, 해당 수열의 구간 합을 출력하는 문제. 세그먼트 트리 방식을 이용하여 풀었으며 입력되는 수들을 배열에 저장, 새로운 배열을 세그먼트 트리화하였다. init, sum, change 함수 모두 재귀적으로 호출하여 사용하였으며 중간 값 나누기 연산을 변수에 할당하여 작지만 연산을 줄여 풀었다. 자세한 풀이는 문제의 주석을 참고</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> sys\n<span class=\"token builtin\">input</span> <span class=\"token operator\">=</span> sys<span class=\"token punctuation\">.</span>stdin<span class=\"token punctuation\">.</span>readline\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">init</span><span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">,</span> start<span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token comment\"># start == end는 리프 노드일 때를 뜻함</span>\n    <span class=\"token comment\"># 리프 노드인 경우 배열의 원소 값을 반환</span>\n    <span class=\"token keyword\">if</span> start <span class=\"token operator\">==</span> end<span class=\"token punctuation\">:</span>\n        tree<span class=\"token punctuation\">[</span>node<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> l<span class=\"token punctuation\">[</span>start<span class=\"token punctuation\">]</span>\n        <span class=\"token keyword\">return</span> tree<span class=\"token punctuation\">[</span>node<span class=\"token punctuation\">]</span>\n\n    <span class=\"token comment\"># 재귀적으로 왼쪽, 오른쪽 자식 트리를 만들고 합을 저장</span>\n    middle <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>start <span class=\"token operator\">+</span> end<span class=\"token punctuation\">)</span> <span class=\"token operator\">//</span> <span class=\"token number\">2</span>\n    tree<span class=\"token punctuation\">[</span>node<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> init<span class=\"token punctuation\">(</span>node<span class=\"token operator\">*</span><span class=\"token number\">2</span><span class=\"token punctuation\">,</span> start<span class=\"token punctuation\">,</span> middle<span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> init<span class=\"token punctuation\">(</span>node<span class=\"token operator\">*</span><span class=\"token number\">2</span><span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> middle<span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> tree<span class=\"token punctuation\">[</span>node<span class=\"token punctuation\">]</span>\n\n<span class=\"token comment\"># 트리의 구역 start, end</span>\n<span class=\"token comment\"># 합을 구할 구역 left, right</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">section_sum</span><span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">,</span> start<span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token comment\"># 합을 구해야하는 구역과 현재 탐색할 트리의 구역이 겹치지 않아 탐색할 필요가 없다</span>\n    <span class=\"token keyword\">if</span> left <span class=\"token operator\">></span> end <span class=\"token keyword\">or</span> right <span class=\"token operator\">&lt;</span> start<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token number\">0</span>\n\n    <span class=\"token comment\"># 범위에 포함될 시 그 자식노드들도 포함이기 때문에 더 이상 호출하지 않아도 된다</span>\n    <span class=\"token keyword\">if</span> left <span class=\"token operator\">&lt;=</span> start <span class=\"token keyword\">and</span> right <span class=\"token operator\">>=</span> end<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> tree<span class=\"token punctuation\">[</span>node<span class=\"token punctuation\">]</span>\n\n    middle <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>start<span class=\"token operator\">+</span>end<span class=\"token punctuation\">)</span><span class=\"token operator\">//</span><span class=\"token number\">2</span>\n    <span class=\"token comment\"># 왼쪽, 오른쪽 자식을 루트로 하는 트리에서 재귀적으로 재탐색</span>\n    <span class=\"token keyword\">return</span> section_sum<span class=\"token punctuation\">(</span>node<span class=\"token operator\">*</span><span class=\"token number\">2</span><span class=\"token punctuation\">,</span> start<span class=\"token punctuation\">,</span> middle<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> section_sum<span class=\"token punctuation\">(</span>node<span class=\"token operator\">*</span><span class=\"token number\">2</span><span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> middle<span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">,</span> left<span class=\"token punctuation\">,</span> right<span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">change_num</span><span class=\"token punctuation\">(</span>node<span class=\"token punctuation\">,</span> start<span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">,</span> index<span class=\"token punctuation\">,</span> diff<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token comment\"># 범위 외일 시 종료</span>\n    <span class=\"token keyword\">if</span> index <span class=\"token operator\">&lt;</span> start <span class=\"token keyword\">or</span> index <span class=\"token operator\">></span> end<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span>\n\n    <span class=\"token comment\"># 트리의 값을 Update</span>\n    tree<span class=\"token punctuation\">[</span>node<span class=\"token punctuation\">]</span> <span class=\"token operator\">+=</span> diff\n\n    <span class=\"token comment\"># 리프 노드가 아닐 경우 자식들도 값을 변경해야하기 때문에 재귀적으로 호출</span>\n    <span class=\"token keyword\">if</span> start <span class=\"token operator\">!=</span> end<span class=\"token punctuation\">:</span>\n        middle <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>start<span class=\"token operator\">+</span>end<span class=\"token punctuation\">)</span><span class=\"token operator\">//</span><span class=\"token number\">2</span>\n        change_num<span class=\"token punctuation\">(</span>node<span class=\"token operator\">*</span><span class=\"token number\">2</span><span class=\"token punctuation\">,</span> start<span class=\"token punctuation\">,</span> middle<span class=\"token punctuation\">,</span> index<span class=\"token punctuation\">,</span> diff<span class=\"token punctuation\">)</span>\n        change_num<span class=\"token punctuation\">(</span>node<span class=\"token operator\">*</span><span class=\"token number\">2</span><span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> middle<span class=\"token operator\">+</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> end<span class=\"token punctuation\">,</span> index<span class=\"token punctuation\">,</span> diff<span class=\"token punctuation\">)</span>\n\n\n<span class=\"token comment\"># 수의 개수, 수의 변경이 일어나는 횟수, 구간의 합을 구하는 횟수</span>\nn<span class=\"token punctuation\">,</span> m<span class=\"token punctuation\">,</span> k <span class=\"token operator\">=</span> <span class=\"token builtin\">map</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">int</span><span class=\"token punctuation\">,</span> <span class=\"token builtin\">input</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\nl <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span>\ntree <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token number\">0</span> <span class=\"token keyword\">for</span> _ <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">3000000</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>\n\n<span class=\"token keyword\">for</span> _ <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span>n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    l<span class=\"token punctuation\">.</span>append<span class=\"token punctuation\">(</span><span class=\"token builtin\">int</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">input</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\ninit<span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> n<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">for</span> _ <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span>m<span class=\"token operator\">+</span>k<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">,</span> c <span class=\"token operator\">=</span> <span class=\"token builtin\">map</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">int</span><span class=\"token punctuation\">,</span> <span class=\"token builtin\">input</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>split<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> a <span class=\"token operator\">==</span> <span class=\"token number\">1</span><span class=\"token punctuation\">:</span>\n        b <span class=\"token operator\">-=</span> <span class=\"token number\">1</span>\n        <span class=\"token comment\"># 현재 인덱스에 있는 수와 바꿔야되는 수의 차이</span>\n        diff <span class=\"token operator\">=</span> c <span class=\"token operator\">-</span> l<span class=\"token punctuation\">[</span>b<span class=\"token punctuation\">]</span>\n        l<span class=\"token punctuation\">[</span>b<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> c\n        change_num<span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> n<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">,</span> diff<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span>section_sum<span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">,</span> n<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> b<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> c<span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>","frontmatter":{"title":"BOJ-2042 - Python","date":"January 03, 2021"}}},"pageContext":{"slug":"/Algorithm/BOJ-2042-Python/","previous":{"fields":{"slug":"/Algorithm/BOJ-1018-Python/"},"frontmatter":{"title":"BOJ-1018 - Python","category":"Algorithm","draft":false}},"next":{"fields":{"slug":"/Algorithm/BOJ-2357-Python/"},"frontmatter":{"title":"BOJ-2357 - Python","category":"Algorithm","draft":false}}}},"staticQueryHashes":["3128451518","3290666882"]}