fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. typedef long long ll;
  5. typedef pair<int, int> ii;
  6.  
  7. const int INF = 1e9;
  8. const ll LINF = 1e18;
  9.  
  10. const int N = 1e5 + 5;
  11. const int LOG = 17;
  12.  
  13. int n, q;
  14. int a[N];
  15.  
  16. int f[LOG][N]; // f[k][i] = gcd của đoạn bắt đầu từ i và có độ dài là 2^k
  17.  
  18. int log2_floor(int x) {
  19. return 31 - __builtin_clz(x);
  20. }
  21.  
  22. void precompute() {
  23. for (int i = 1; i <= n; i++) f[0][i] = a[i];
  24.  
  25. for (int k = 1; k < LOG; k++) {
  26. for (int i = 1; i + (1 << k) - 1 <= n; i++) {
  27. f[k][i] = __gcd(f[k - 1][i], f[k - 1][i + (1 << (k - 1))]);
  28. }
  29. }
  30. }
  31.  
  32. int getGCD(int l, int r) {
  33. int k = log2_floor(r - l + 1);
  34. return __gcd(f[k][l], f[k][r - (1 << k) + 1]);
  35. }
  36.  
  37. // Tìm vị trí j đầu tiên > i sao cho getGCD(l, j) < g
  38. int findNext(int l, int i, int g) {
  39. int lo = i + 1, hi = n, ans = n + 1;
  40.  
  41. while (lo <= hi) {
  42. int mid = (lo + hi) >> 1;
  43.  
  44. if (getGCD(l, mid) < g) {
  45. ans = mid;
  46. hi = mid - 1;
  47. }
  48. else {
  49. lo = mid + 1;
  50. }
  51. }
  52.  
  53. return ans;
  54. }
  55.  
  56. map<int, ll> ans; // ans[x] = (Số đoạn có gcd = x)
  57.  
  58. int main() {
  59. ios::sync_with_stdio(0); cin.tie(0);
  60. cin >> n;
  61. for (int i = 1; i <= n; i++) cin >> a[i];
  62.  
  63. precompute();
  64.  
  65. // Nhận xét quan trọng:
  66. // Khi chốt đầu mút l thì ta có tối đa O(log2(a[l])) giá trị gcd phân biệt khi xét mọi đoạn [l, r] (l <= r)
  67. // ~ O(n * log2(MAX_A) * log2(n * log2(MAX_A))
  68. for (int l = 1; l <= n; l++) { // chốt đầu mút l
  69. for (int i = l; i <= n; ) {
  70. int g = getGCD(l, i);
  71. int j = findNext(l, i, g);
  72. ans[g] += j - i; // với r nằm trong đoạn [i, j - 1] thì ta có getGCD(l, r) = g
  73. i = j;
  74. }
  75. }
  76.  
  77. cin >> q;
  78.  
  79. while (q--) {
  80. int x; cin >> x;
  81. cout << (ans.count(x) ? ans[x] : 0) << '\n';
  82. }
  83. }
Success #stdin #stdout 0.01s 5288KB
stdin
3
2 6 3
5
1
2
3
4
6
stdout
1
2
2
0
1