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