<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bruno Papa</title>
    <description>The latest articles on DEV Community by Bruno Papa (@brpapa).</description>
    <link>https://dev.to/brpapa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F277884%2Feb73816c-ed21-4b2e-892f-13cceb330f2e.jpeg</url>
      <title>DEV Community: Bruno Papa</title>
      <link>https://dev.to/brpapa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brpapa"/>
    <language>en</language>
    <item>
      <title>My Recursion Tree Visualizer project went viral on Linkedin</title>
      <dc:creator>Bruno Papa</dc:creator>
      <pubDate>Sun, 04 Oct 2020 00:34:16 +0000</pubDate>
      <link>https://dev.to/brpapa/i-built-a-recursion-tree-visualizer-1l49</link>
      <guid>https://dev.to/brpapa/i-built-a-recursion-tree-visualizer-1l49</guid>
      <description>&lt;p&gt;Recently I finished my favorite side project by now.&lt;/p&gt;

&lt;p&gt;It is a Recursion Tree Visualizer that helps programmers understand recursion. You input any recursive function using javascript code and visualize your corresponding recursion tree.&lt;/p&gt;

&lt;p&gt;I first published this in my Linkedin profile and I was surprised by the quick engagement that the &lt;a href="https://www.linkedin.com/feed/update/urn:li:activity:6716531439292211200/" rel="noopener noreferrer"&gt;post&lt;/a&gt; generated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1pi68zg0ynq9y4gdwfwq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1pi68zg0ynq9y4gdwfwq.png" alt="Screen Shot 2020-10-03 at 21.40.35"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More than 15K views and more than 1K likes in just a few days 🤯.&lt;/p&gt;

&lt;p&gt;If you want just to try it out, access &lt;a href="https://recursion.now.sh" rel="noopener noreferrer"&gt;https://recursion.now.sh&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Árvore de segmentos com RMQ</title>
      <dc:creator>Bruno Papa</dc:creator>
      <pubDate>Sun, 26 Jan 2020 10:01:12 +0000</pubDate>
      <link>https://dev.to/brpapa/arvore-de-segmentos-com-rmq-31j</link>
      <guid>https://dev.to/brpapa/arvore-de-segmentos-com-rmq-31j</guid>
      <description>&lt;p&gt;Uma árvore de segmentos é uma representação de segmentos de um vetor em uma &lt;strong&gt;árvore binária&lt;/strong&gt; para que consultas em um dado segmento possam ser feitas de forma eficiente com complexidade de tempo &lt;strong&gt;O(log(N))&lt;/strong&gt;, uma vantagem importante, visto que N pode ser excessivamente grande.&lt;/p&gt;

&lt;p&gt;Mas é importante deixar claro que:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;O custo de sua implementação só compensa os seus ganhos se o vetor for frequentemente atualizado e várias consultas sejam requeridas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Para entender minha implementação, considere que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nos foi dado um vetor &lt;code&gt;arr&lt;/code&gt; de tamanho N.&lt;/li&gt;
&lt;li&gt;A árvore binária é armazenada como um vetor &lt;code&gt;bt&lt;/code&gt; com tamanho de até 4*N, onde 0 é o índice da raiz, &lt;code&gt;bt[v]&lt;/code&gt; o valor do vértice v, e &lt;code&gt;bt[v*2+1]&lt;/code&gt; e &lt;code&gt;bt[v*2+2]&lt;/code&gt; o valor de seus filhos à esquerda e à direita, respectivamente.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Está confuso? Calma! Abaixo vamos aplicá-la à uma RMQ para entender seu funcionamento de forma visual antes de ir para o código.&lt;/p&gt;

&lt;h1&gt;
  
  
  Range Minimum Query (RMQ)
&lt;/h1&gt;

&lt;p&gt;Encontre o menor valor no sub-vetor {arr[i], …, arr[j]}, sendo 0 &amp;lt; i ≤ j&amp;lt; N.&lt;/p&gt;

&lt;h2&gt;
  
  
  build bt
&lt;/h2&gt;

&lt;p&gt;A raiz, &lt;code&gt;bt[0]&lt;/code&gt;, representa o segmento [0 .. N-1] de &lt;code&gt;arr&lt;/code&gt;. Para cada vértice representante de um segmento [l .. r], divide-o em dois segmentos menores: [l .. (l+r)/2] e [(l+r)/2+1 .. r].&lt;/p&gt;

&lt;p&gt;Abaixo um exemplo da árvore de segmentos, após buildBT, com arr = {18, 17, 13, 19, 15, 11, 20} e N = 7.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A9a_fRNZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2980/1%2ARSp40bSa4qdAODqvvvTkZg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9a_fRNZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2980/1%2ARSp40bSa4qdAODqvvvTkZg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Executamos &lt;code&gt;bt.assign(4*N,0)&lt;/code&gt; e, em seguida, chamamos &lt;code&gt;buildBT(0, 0, N-1)&lt;/code&gt; para construir os valores iniciais da nossa árvore de segmentos em O(N*log(N)).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  range query
&lt;/h2&gt;

&lt;p&gt;Como o algoritmo divide intervalos sucessivamente, conseguimos consultar um intervalo qualquer em complexidade de tempo O(log(N)).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Por exemplo, observe que &lt;code&gt;rangeQuery(0, 0, N-1, 1, 3)&lt;/code&gt; nos retornará 13, como descrito no diagrama abaixo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lA9UzLZv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2940/1%2AoFfcsXOVo0KN7uusD9PNuw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lA9UzLZv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://miro.medium.com/max/2940/1%2AoFfcsXOVo0KN7uusD9PNuw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  point update
&lt;/h2&gt;

&lt;p&gt;Caso o vetor &lt;code&gt;arr&lt;/code&gt; mude em alguma posição &lt;code&gt;i&lt;/code&gt;, basta usar as mesmas ideias utilizadas acima para atualizar &lt;code&gt;bt&lt;/code&gt; em O(log(N)).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Considerações finais
&lt;/h1&gt;

&lt;p&gt;Por hoje é só. Vimos que uma árvore de segmentos nos permite fazer consultas eficientes, mas sua implementação é recursiva e, por isso, é preciso estar atento à muitos detalhes.&lt;/p&gt;

&lt;p&gt;Agradeço a sua leitura, e espero que eu tenha contribuído em, pelo menos, colocar dúvidas na sua cabeça.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Referências bibliográficas:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HALIM, Steven. HALIM, Felix. Competitive Programming 3: "the new lower bound of programming contests". Chapter 2.4.3. 2013.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>computerscience</category>
      <category>cpp</category>
    </item>
  </channel>
</rss>
