<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.algopedia.ro/wiki/index.php?action=history&amp;feed=atom&amp;title=Cerc_6_2018_lectia_2</id>
	<title>Cerc 6 2018 lectia 2 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.algopedia.ro/wiki/index.php?action=history&amp;feed=atom&amp;title=Cerc_6_2018_lectia_2"/>
	<link rel="alternate" type="text/html" href="https://www.algopedia.ro/wiki/index.php?title=Cerc_6_2018_lectia_2&amp;action=history"/>
	<updated>2026-04-19T10:37:30Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://www.algopedia.ro/wiki/index.php?title=Cerc_6_2018_lectia_2&amp;diff=15664&amp;oldid=prev</id>
		<title>Bella: Created page with &quot;= Lectie =  == Descompunerea in factori primi == O implementare a acestei probleme de complexitate O(sqrt(n)): &lt;syntaxhighlight&gt; #include &lt;stdio.h&gt;  int main() {   int n, div,...&quot;</title>
		<link rel="alternate" type="text/html" href="https://www.algopedia.ro/wiki/index.php?title=Cerc_6_2018_lectia_2&amp;diff=15664&amp;oldid=prev"/>
		<updated>2018-10-13T20:40:42Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;= Lectie =  == Descompunerea in factori primi == O implementare a acestei probleme de complexitate O(sqrt(n)): &amp;lt;syntaxhighlight&amp;gt; #include &amp;lt;stdio.h&amp;gt;  int main() {   int n, div,...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Lectie = &lt;br /&gt;
== Descompunerea in factori primi ==&lt;br /&gt;
O implementare a acestei probleme de complexitate O(sqrt(n)):&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main() {&lt;br /&gt;
  int n, div, exp;&lt;br /&gt;
&lt;br /&gt;
  scanf(&amp;quot;%d&amp;quot;, &amp;amp;n);&lt;br /&gt;
  div = 2; //Incepem cautarea factorilor primi de la primul numar prim&lt;br /&gt;
  while ( div * div &amp;lt;= n ) { //Cautam factorii primi pana la radicalul lui n&lt;br /&gt;
    exp = 0;&lt;br /&gt;
    while ( n % div == 0 ) {&lt;br /&gt;
      n /= div;&lt;br /&gt;
      exp++;&lt;br /&gt;
    }&lt;br /&gt;
    if (exp &amp;gt; 0)&lt;br /&gt;
      printf(&amp;quot;%d^%d\n&amp;quot;, div, exp);&lt;br /&gt;
    div++;&lt;br /&gt;
  }&lt;br /&gt;
  // daca n mai contine un factor, el este un numar prim la puterea unu&lt;br /&gt;
  if ( n &amp;gt; 1 )&lt;br /&gt;
    printf( &amp;quot;%d^1\n&amp;quot;, n );&lt;br /&gt;
&lt;br /&gt;
  return 0;&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Numarul de divizori si suma divizorilor ==&lt;br /&gt;
&lt;br /&gt;
Fie descompunerea unui numar n in factori primi:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
n= d_1^{p_1} \ast d_2^{p_2} \ast ... \ast d_k^{p_k}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Numarul de divizori va fi:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathit{nrdiv}=\left({p}_{1}+1\right)\ast \left({p}_{2}+1\right)\ast \mathrm{...}\ast \left({p}_{k}+1\right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Suma divizorilor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\mathit{sdiv}=\frac{{d}_{1}^{p1+1}-1}{{d}_{1}-1}\ast \frac{{d}_{2}^{p2+1}-1}{d2-1}\ast \mathrm{...}\ast \frac{{d}_{k}^{\mathit{pk}+1}-1}{{d}_{k}-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Vezi demonstratia matematica a formulelor in caiet&lt;br /&gt;
&lt;br /&gt;
=== Studiu de caz Problema divmul - infoarena ===&lt;br /&gt;
In caiete&lt;br /&gt;
&lt;br /&gt;
== Ciurul lui Eratostene ==&lt;br /&gt;
Reamintim aici doar algoritmul studiat anul trecut:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;char ciur[2000000];&lt;br /&gt;
...&lt;br /&gt;
fscanf( fin, &amp;quot;%d&amp;quot;, &amp;amp;n );&lt;br /&gt;
for ( d = 2; d * d &amp;lt;= n; d++ )&lt;br /&gt;
  if ( ciur[d] == 0 ) // daca d este prim&lt;br /&gt;
    for ( i = d * d; i &amp;lt;= n; i = i + d ) // vom marca numerele din d in d&lt;br /&gt;
      ciur[i] = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Varianta usor optimizata ===&lt;br /&gt;
Pentru un numar d prim, vom marca toti multiplii acestuia, nepari&lt;br /&gt;
Ex: pentru d = 7, marcam multiplii: 7*7, 7*9, 7*11...sarind peste 7*8, &amp;amp;*10...&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;char ciur[2000000];&lt;br /&gt;
...&lt;br /&gt;
fscanf( fin, &amp;quot;%d&amp;quot;, &amp;amp;n );&lt;br /&gt;
for ( d = 4; d &amp;lt;= n; d += 2 )&lt;br /&gt;
  ciur[d] = 1;&lt;br /&gt;
for ( d = 3; d * d &amp;lt;= n; d+= 2 )&lt;br /&gt;
  if ( ciur[d] == 0 ) // daca d este prim&lt;br /&gt;
    for ( i = d * d; i &amp;lt;= n; i = i + 2 * d ) // vom marca numerele din 2d in 2d&lt;br /&gt;
      ciur[i] = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Putem de asemenea sa optimizam si memoria folosita, pastrand valorile ciurului doar pentru elementele impare.&lt;br /&gt;
 &lt;br /&gt;
 ciur[1] va retine daca 3 e prim&lt;br /&gt;
 ciur[2] va retine daca 5 e prim&lt;br /&gt;
 ciur[3] va retine daca c7 e prim&lt;br /&gt;
 ciur[d/2] va retine daca d e prim&lt;br /&gt;
 Adica:&lt;br /&gt;
 ciur[k] va retine daca 2k + 1 e prim&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
char ciur[2000000];&lt;br /&gt;
for ( d = 3; d * d &amp;lt;= n; d+= 2 )&lt;br /&gt;
  if ( ciur[d/2] == 0 ) // daca d este prim&lt;br /&gt;
    for ( i = d * d; i &amp;lt;= n; i = i + 2 * d ) &lt;br /&gt;
      ciur[i/2] = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Utilizarea Ciurului lui Eratostene ==&lt;br /&gt;
===Calcului numarului de divizori ===&lt;br /&gt;
Putem modifica modul de parcurgere al vectorului pentru a calcula numarul de divizori pentru numerele de la 1 la n:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int num_div[2000000];&lt;br /&gt;
...&lt;br /&gt;
fscanf( fin, &amp;quot;%d&amp;quot;, &amp;amp;n );&lt;br /&gt;
for ( d = 1; d &amp;lt;= n; d++ )&lt;br /&gt;
  for ( i = d; i &amp;lt;= n; i = i + d )&lt;br /&gt;
    num_div[i]++;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Calcului sumei divizorilor ===&lt;br /&gt;
De asemenea putem calcula similar suma divizorilor pentru numerele de la 1 la n:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
int sum_div[2000000];&lt;br /&gt;
...&lt;br /&gt;
fscanf( fin, &amp;quot;%d&amp;quot;, &amp;amp;n );&lt;br /&gt;
for ( d = 1; d &amp;lt;= n; d++ )&lt;br /&gt;
  for ( i = d; i &amp;lt;= n; i = i + d )&lt;br /&gt;
    sum_div[i] = sum_div[i] + d;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nu uitați:&lt;br /&gt;
* Vectorul &amp;lt;tt&amp;gt;ciur[]&amp;lt;/tt&amp;gt; este de tip caracter și nu întreg!&lt;br /&gt;
* În final vectorul &amp;lt;tt&amp;gt;ciur[i]&amp;lt;/tt&amp;gt; este &amp;lt;tt&amp;gt;0&amp;lt;/tt&amp;gt; dacă numărul este prim sau &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt; în caz contrar.&lt;br /&gt;
&lt;br /&gt;
Complexitate? Matematica este complexă, dar rețineți că metoda este aproximativ &amp;#039;&amp;#039;O(n)&amp;#039;&amp;#039; pentru valorile lui n cu care vom lucra noi. Pentru cei interesați, complexitatea este de fapt &amp;#039;&amp;#039;O(n∙log&amp;amp;nbsp;log&amp;amp;nbsp;n)&amp;#039;&amp;#039;.&lt;br /&gt;
&lt;br /&gt;
== TEMA ==&lt;br /&gt;
=== Descompunere in factori primi si nr divizoril ===&lt;br /&gt;
* [http://varena.ro/problema/nenepatrat nepatrat][http://isa.algopedia.ro/wiki/index.php/nenepatrat Rez]&lt;br /&gt;
* [https://www.infoarena.ro/problema/divmul divmul][http://isa.algopedia.ro/wiki/index.php/divmul Rez]&lt;br /&gt;
&lt;br /&gt;
=== Ciur ===&lt;br /&gt;
* [http://varena.ro/problema/paisprezece paisprezece] [http://isa.algopedia.ro/wiki/index.php/paisprezece Rez]&lt;br /&gt;
* [https://infoarena.ro/problema/prim prim][http://isa.algopedia.ro/wiki/index.php/prim Rez]&lt;/div&gt;</summary>
		<author><name>Bella</name></author>
	</entry>
</feed>