Advertisement
a53

cmmdc4

a53
Nov 20th, 2020
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.05 KB | None | 0 0
  1. /*
  2. * Cmmdc - O(N*logN)
  3. * Bogdan Iordache
  4. * scor: 100
  5. */
  6. #include <bits/stdc++.h>
  7. using namespace std;
  8.  
  9. const int kMaxN = 1000005;
  10. const int kMod = 1000000007;
  11.  
  12. int sum_multiple_pairs[kMaxN];
  13. int sum_cmmdc_pairs[kMaxN];
  14. int sum_multiples[kMaxN];
  15.  
  16. int main() {
  17. int N;
  18. cin >> N;
  19.  
  20. // determinam pentru fiecare c, suma produselor de perechi de multipli
  21. for (int c = 1; c <= N; ++c) {
  22. // acest pas se poate rezolva in O(1) cu formule pentru suma de numere
  23. // consecutive, respectiv patrate consecutive, insa intrucat nu
  24. // afecteaza complexitatea pe mai departe, preferam metoda de mai jos
  25. // pentru a asigura o limita de timp mai robusta
  26. int simple_sum = 0;
  27. int squares_sum = 0;
  28. for (int a = c; a <= N; a += c) {
  29. simple_sum = (simple_sum + a) % kMod;
  30. squares_sum = (squares_sum + 1LL * a * a) % kMod;
  31. }
  32.  
  33. sum_multiple_pairs[c] =
  34. (1LL * simple_sum * simple_sum % kMod - squares_sum + kMod) % kMod;
  35. sum_multiples[c] = (simple_sum + kMod - c) % kMod;
  36. }
  37.  
  38. // idee: daca c divide perechea (a, b), fie c este cmmdc(a, b), fie c divide
  39. // cmmdc(a, b). Calculam in ordine descrescatoare pentru fiecare c suma
  40. // produselor de perechi pentru care c este cmmdc, scazand din suma de
  41. // perechi de multipli sumele de cmmdc ale tuturor multiplilor lui c. Acesta
  42. // este pasul care forteaza complexitatea de O(NlogN)
  43. for (int c = N; c; --c) {
  44. sum_cmmdc_pairs[c] = sum_multiple_pairs[c];
  45. for (int mc = 2 * c; mc <= N; mc += c)
  46. sum_cmmdc_pairs[c] =
  47. (1LL * sum_cmmdc_pairs[c] + kMod - sum_cmmdc_pairs[mc]) % kMod;
  48. }
  49.  
  50. int res = 0;
  51. for (int c = 1; c <= N; ++c) {
  52. // scadem perechile de forma (m*c, c, c) sau (c, m*c, c)
  53. res = (res + 1LL * c *
  54. (sum_cmmdc_pairs[c] -
  55. 2LL * c * sum_multiples[c] % kMod + kMod)) %
  56. kMod;
  57. }
  58. cout << res << endl;
  59.  
  60. return 0;
  61. }
  62.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement