Advertisement
a53

GCD2

a53
Jul 31st, 2021
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.41 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. ifstream fin("gcd2.in");
  4. ofstream fout("gcd2.out");
  5. vector<vector<long long>> rmq;
  6. vector<long long> lg;
  7.  
  8. //calculeaza cmmdc(a,b)
  9. long long gcd(long long a, long long b) {
  10. while (b) {
  11. long long c = a % b;
  12. a = b;
  13. b = c;
  14. }
  15. return a;
  16. }
  17.  
  18. //returneaza valoarea cmmdcului secventei st...dr
  19. long long query(long long st, long long dr) {
  20. long long power = lg[dr - st + 1] - 1;
  21. return gcd(rmq[st][power], rmq[dr - (1 << power) + 1][power]);
  22. }
  23.  
  24. int main() {
  25.  
  26. //citirea
  27. long long n;
  28. fin >> n;
  29. vector<long long> a(n + 1);
  30. for (long long i = 1; i <= n; ++i) {
  31. fin >> a[i];
  32. }
  33.  
  34. //precompute la floorul logaritmilor
  35. lg = vector<long long>(n + 1);
  36. for (long long i = 1; i <= n; ++i) {
  37. lg[i] = lg[i / 2] + 1;
  38. }
  39.  
  40. //calulam dinamica pentru RMQ
  41. rmq = vector<vector<long long>>(n + 1, vector<long long>(lg[n] + 1));
  42. for (long long i = 1; i <= n; ++i) {
  43. rmq[i][0] = a[i];
  44. }
  45. for (long long j = 1; j <= lg[n]; ++j) {
  46. for (long long i = 1; i + (1 << j) - 1 <= n; ++i) {
  47. rmq[i][j] = gcd(rmq[i][j - 1], rmq[i + (1 << (j - 1))][j - 1]);
  48. }
  49. }
  50.  
  51. long long ans = 0;
  52. long long unde = 0;
  53. vector<long long> rez(n + 1);
  54. for (long long i = n; i >= 1; --i) {
  55. long long p = i;
  56. long long cmmdc = a[i];
  57.  
  58. //caz special
  59. if (a[i] == 0) {
  60. rez[i] = rez[unde];
  61. continue;
  62. }
  63.  
  64. //cat timp exista alte cmmdcuri posibile le cautam
  65. while (true) {
  66. long long st = p + 1, dr = n;
  67. long long rep = n + 1;
  68. while (st <= dr) {
  69. long long mid = (st + dr) / 2;
  70. if (query(i, mid) < cmmdc) {
  71. dr = mid - 1;
  72. rep = mid;
  73. }
  74. else {
  75. st = mid + 1;
  76. }
  77. }
  78. rez[i] += ((rep * 1ll) - (p * 1ll)) * (cmmdc * 1ll);
  79. if (rep == n + 1) {
  80. break;
  81. }
  82. p = rep;
  83. cmmdc = query(i, rep);
  84. }
  85.  
  86. //pentru cazul special
  87. if (a[i] > 0) {
  88. unde = i;
  89. }
  90. }
  91.  
  92. //calculam raspunsul
  93. for (long long i = 1; i <= n; ++i) {
  94. ans += rez[i];
  95. }
  96. fout << ans;
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement