Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pa:laboratoare:laborator-02 [2026/03/15 17:44]
matei.mantu Explain binary exponentiation
pa:laboratoare:laborator-02 [2026/03/15 19:10] (current)
aureliu.antonie [Gardurile lui Gigel]
Line 359: Line 359:
     * $dp[i] = (dp[i-1] + dp[i-4]) \ \% \  MOD$      * $dp[i] = (dp[i-1] + dp[i-4]) \ \% \  MOD$ 
     *      * 
-<​note>​ Așa cum am zis în secțiunea de [[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-04?&#​sfaturireguli|sfaturi și reguli]] vrem să facem o **parționare** după un anumit **criteriu**:​ în cazul problemei de față, criteriul de parționare este dacă gardul se termină cu o scândură verticală sau orizontală.+<​note>​ Așa cum am zis în secțiunea de [[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-02?&#​sfaturireguli|sfaturi și reguli]] vrem să facem o **parționare** după un anumit **criteriu**:​ în cazul problemei de față, criteriul de parționare este dacă gardul se termină cu o scândură verticală sau orizontală.
  
  
-De asemenea, tot în secțiunea [[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-04?&#​sfaturireguli|sfaturi și reguli]] am precizat că nu vrem **să număram un obiect** (un mod de a construi gardul) **de două ori**. Recurența noastră (dp[i] = dp[i-1] + dp[i-4]) nu ia un obiect de două ori pentru că orice soluție care vine din dp[i-4] e diferită de alta care vine din dp[i-1] pentru că diferă în cel puțin ultima scândură așezată) </​note> ​+De asemenea, tot în secțiunea [[http://​ocw.cs.pub.ro/​courses/​pa/​laboratoare/​laborator-02?&#​sfaturireguli|sfaturi și reguli]] am precizat că nu vrem **să număram un obiect** (un mod de a construi gardul) **de două ori**. Recurența noastră (dp[i] = dp[i-1] + dp[i-4]) nu ia un obiect de două ori pentru că orice soluție care vine din dp[i-4] e diferită de alta care vine din dp[i-1] pentru că diferă în cel puțin ultima scândură așezată) </​note> ​
  
 == Implementare recurență == == Implementare recurență ==
Line 498: Line 498:
 $$S_i = S_{k}C^{i -k}$$ $$S_i = S_{k}C^{i -k}$$
  
-Pentru a aduce un plus de viteză, vom folosi un truc numit **exponențiere rapidă**. Pe scurt, vom ridica o valoare(notată $a$) la puterea n, împărțind ​ n folosind reprezentarea sa binară.+Pentru a aduce un plus de viteză, vom folosi un truc numit [[https://​en.wikipedia.org/​wiki/​Exponentiation_by_squaring|exponențiere rapidă]]. Pe scurt, vom ridica o valoare(notată $a$) la puterea n, împărțind ​ n folosind reprezentarea sa binară.
  
-De exemplu, dacă am vrea să calculăm+De exemplu, dacă am vrea să calculăm:
 $$ 5^{13} = 5^{1101_2}= 5^8 * 5^4 * 5^1 $$ $$ 5^{13} = 5^{1101_2}= 5^8 * 5^4 * 5^1 $$
  
 Exponentul are exact $\lfloor log_2(n) \rfloor + 1$ cifre în baza 2, deci vom avea nevoie de $O(log(n))$ înmulțiri,​ fiind condiționați de faptul că trebuie să cunoaștem $a^1, a^2, a^4, etc.$ Din fericire, putem calcula rapid acești factori prin ridicarea la pătrat a elementului precedent. Exponentul are exact $\lfloor log_2(n) \rfloor + 1$ cifre în baza 2, deci vom avea nevoie de $O(log(n))$ înmulțiri,​ fiind condiționați de faptul că trebuie să cunoaștem $a^1, a^2, a^4, etc.$ Din fericire, putem calcula rapid acești factori prin ridicarea la pătrat a elementului precedent.
  
-În final, putem implementa un algoritm iterativ pentru calcularea rezultatului $a^n$ iterând prin cifrele din baza 2 ale lui n și înmulțind cu ${a^2}^{k}$ atunci când cifra curentă este 1.(pentru viteză, vom folosi operații pe biți)+În final, putem implementa un algoritm iterativ pentru calcularea rezultatului $a^n$ iterând prin cifrele din baza 2 ale lui n și înmulțind cu ${a^2}^{k}$ atunci când cifra curentă este 1(pentru viteză, vom folosi operații pe biți în loc de o iterare propriu zisă prin cifre).
  
 Mai jos putem vedea o implementare in C++: Mai jos putem vedea o implementare in C++:
Line 526: Line 526:
 } }
 </​code>​ </​code>​
 +
 +Acest truc poate fi folosit pentru orice tip de date pentru care înmulțirea este asociativă(inclusiv matrice).
 +
 Obținem astfel o soluție cu următoarele complexități:​ Obținem astfel o soluție cu următoarele complexități:​
   * ** complexitate temporală **: $T = O(KMAX^3 * log(n))$   * ** complexitate temporală **: $T = O(KMAX^3 * log(n))$
pa/laboratoare/laborator-02.1773589492.txt.gz · Last modified: 2026/03/15 17:44 by matei.mantu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0