Cod sursa(job #2783278)

Utilizator FilippppFilip Gruianu Filipppp Data 14 octombrie 2021 09:48:00
Problema Fractii Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.66 kb
#include <bits/stdc++.h>

/**

phi(n) = nr numerelor <= n care sunt prime cu n

phi(n) = n * (produs())

n = 10 => phi(10) = n * (2-1)/2 * (5-1)/5 = 10 * 1/2 * 4/5 = 5*4/5 = 4

n = 12 => phi(12) = n * (2-1)/2 * (3-1)/3
(2, 3)

phi(p1^e1*p2^e2..*pk^ek) = p1^e1*p2^e2..*pk^ek * (p1-1)/p1 * (p2-1)/p2 * .. * (pk-1)/pk



**/

using namespace std;

int gcd(int a, int b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}

bool e[1000000 + 7];
int phi[1000000 + 7];

int main() {
  freopen ("fractii.in", "r", stdin);
  freopen ("fractii.out", "w", stdout);
  int n;
  long long cnt = 0;
  cin >> n;

  for (int i = 1; i <= n; i++) {
    phi[i] = i;
  }

  for (int i = 2; i <= n; i++) {
    e[i] = 1;
  }
  for (int i = 2; i * i <= n; i++) {
    if (e[i]) {
      for (int j = i * i; j <= n; j += i) {
        e[j] = 0;
      }
    }
  }

  /**for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= i; j++) {
      if (e[j] and i % j == 0) {
        phi[i] = phi[i] / j * (j - 1);
      }
    }
  }**/

  for (int j = 1; j <= n; j++) {
    if (e[j]) {
      for (int i = j; i <= n; i += j) {
        phi[i] = phi[i] / j * (j - 1);
      }
    }
  }


/**
parcurgem i si dupa toti divizorii lui (si le spunem j)
sa parcurgem j si dupa toti multiplii lui (si le spunem i)

n*logn

  i=1 => 1 pas
  i=2 => 2 pasi

  ...
  i=n => n pasi
  1+2+...+n=n*(n+1)/2=1.000.000*1.000.001/2>2*10^8
**/



  for (int q = 1; q <= n; q++) {
    cnt += phi[q];
    /**for (int p = 1; p <= q; p++) {
      if (__gcd(p, q) == 1) {
        cnt++;
      }
    }**/
  }



  cout << cnt * 2 - 1 << "\n";
  return 0;
}