<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>競技プログラミング | 背景</title>
	<atom:link href="https://moonpeta.com/category/programming/kyopro/feed/" rel="self" type="application/rss+xml" />
	<link>https://moonpeta.com</link>
	<description></description>
	<lastBuildDate>Thu, 09 Jan 2025 02:36:30 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://moonpeta.com/wp-content/uploads/2023/10/cropped-wraith_logo_ribon_pink-32x32.png</url>
	<title>競技プログラミング | 背景</title>
	<link>https://moonpeta.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>完全二分木では0-indexedより1-indexedのほうがいいよって話</title>
		<link>https://moonpeta.com/programming/0inxvs1idx/</link>
					<comments>https://moonpeta.com/programming/0inxvs1idx/#respond</comments>
		
		<dc:creator><![CDATA[フローラ]]></dc:creator>
		<pubDate>Wed, 02 Mar 2022 04:09:18 +0000</pubDate>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[競技プログラミング]]></category>
		<category><![CDATA[0 based]]></category>
		<category><![CDATA[1 based]]></category>
		<category><![CDATA[tree]]></category>
		<category><![CDATA[二分木]]></category>
		<guid isPermaLink="false">https://www.fruity-floral.com/?p=1546</guid>

					<description><![CDATA[　完全二分木はこういうやつです。 　最下層以外の全部の層がノードで埋められ、最下層のnodeは左に詰められているような二分木です（別の定義もある）。 　完全二分木では配列を使って木を管理できることが知られています。具体的 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>　完全二分木はこういうやつです。</p>



<figure class="wp-block-image size-full"><a href="https://moonpeta.com/wp-content/uploads/2022/03/Graph.gv_.png"><img fetchpriority="high" decoding="async" width="755" height="347" src="https://moonpeta.com/wp-content/uploads/2022/03/Graph.gv_.png" alt="" class="wp-image-1547" srcset="https://moonpeta.com/wp-content/uploads/2022/03/Graph.gv_.png 755w, https://moonpeta.com/wp-content/uploads/2022/03/Graph.gv_-300x138.png 300w" sizes="(max-width: 755px) 100vw, 755px" /></a><figcaption>1-indexedの完全二分木</figcaption></figure>



<p>　最下層以外の全部の層がノードで埋められ、最下層のnodeは左に詰められているような二分木です（別の定義もある）。</p>



<p>　完全二分木では配列を使って木を管理できることが知られています。具体的には</p>



<ul class="wp-block-list"><li>0-indexed<br>rootは0<br>node \(\ i\)の親、左の子、右の子はそれぞれ\(\ (i-1)/2,\,2i+1,\,2i+2\)</li><li>1-indexed<br>rootは1<br>node \(\ i\)の親、左の子、右の子はそれぞれ\(\ i/2,\,2i,\,2i+1\)</li></ul>



<p>　割り算は切り捨てです。<br>　このふたつは同じように見えて実装上少し違います。1-indexedはすべての演算をbit演算に置き換えることができるからです。つまり\(\ i\)に対して</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-python" data-lang="Python"><code>#親
i&gt;&gt;1
#左の子
i&lt;&lt;1
#右の子
i&lt;&lt;1|1</code></pre></div>



<p>　一般にbit演算のほうがはやいので、速度が要求されるときは1-indexedにしたほうがいいでしょう。<br>　ためしに計算してみると<br></p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-python" data-lang="Python"><code>import time
import numpy as np


np.random.seed(0)
A = np.random.randint(1, 10**8, 10**8)

# 0-indexed
time_memo = time.time()
for i in A:
    work = (i - 1) // 2, 2 * i + 1, 2 * i + 2
print(f&quot;{time.time()-time_memo} sec&quot;)

# 1-indexed
time_memo = time.time()
for i in A:
    work = i &gt;&gt; 1, i &lt;&lt; 1, i &lt;&lt; 1 | 1
print(f&quot;{time.time()-time_memo} sec&quot;)
</code></pre></div>



<div class="hcb_wrap"><pre class="prism line-numbers lang-plain" data-file="出力結果"><code>53.23937201499939 sec
37.52551341056824 sec</code></pre></div>



<p>となり、1-indexedのほうがそこそこ速いです。</p>



<p>　私はもともと0-indexedにこだわっていたんですが、0-indexedで実装したセグメント木で以下の問題を解いたときにTLEして、1-indexedにしたら間に合うということが起きたので、1-indexed派になりました。</p>



<p>問題：<br><a rel="noopener" target="_blank" href="https://yukicoder.me/problems/no/877" data-type="URL" data-id="https://yukicoder.me/problems/no/877">No.877 Range ReLU Query<span class="fa fa-external-link external-icon anchor-icon"></span></a></p>



<p>　0-indexedにこだわるのもよくないので1-indexedにしましょう！</p>



<h3 class="wp-block-heading">姉妹へのアクセス</h3>



<p>　また0-indexedでできなくて1-indexedではできることがひとつあります。それが姉妹へのアクセスです。姉妹というのは同じ親をもつもう片割れのnodeのことです。1-indexedで自分が\(\ i\)のとき、姉妹へのアクセスは以下のようにできます。</p>



<div class="hcb_wrap"><pre class="prism line-numbers lang-python" data-lang="Python"><code>#姉妹
i^1</code></pre></div>



<p>　この演算は\(\ i\)の1ケタ目だけをひっくり返す操作になっており、1-indexedでは左右の子の間でケタ上がりがないため、この操作が左右を行き来することに対応しています（左が偶数右が奇数なのがポイント）。<br>　一方で0-indexedでは、左右の子の間でケタ上がりが起きるためこのような簡単な記述はできません<br>　なので姉妹へのアクセスが必要なときなどはさらに1-indexedが優位になりますね。</p>



<p>　まとめるとこんな感じ</p>



<figure class="wp-block-image size-full is-resized"><a href="https://moonpeta.com/wp-content/uploads/2022/03/Graph3-1.png"><img decoding="async" src="https://moonpeta.com/wp-content/uploads/2022/03/Graph3-1.png" alt="" class="wp-image-1579" width="335" height="340" srcset="https://moonpeta.com/wp-content/uploads/2022/03/Graph3-1.png 247w, https://moonpeta.com/wp-content/uploads/2022/03/Graph3-1-100x100.png 100w" sizes="(max-width: 335px) 100vw, 335px" /></a><figcaption>1-indexedにおける親子の関係</figcaption></figure>
]]></content:encoded>
					
					<wfw:commentRss>https://moonpeta.com/programming/0inxvs1idx/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
