Advertisement
siiena

rangegcd

Feb 20th, 2020
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.77 KB | None | 0 0
  1. #include <stdio.h>
  2.  
  3. int ST[300000][20], lg[300000];
  4.  
  5. int nod(int a, int b) {
  6.     while (a && b) {
  7.         if (a >= b) a %= b;
  8.         else b %= a;
  9.     }
  10.     return a | b;
  11. }
  12.  
  13. int query(int l, int r, int lg[]) {
  14.     int j = lg[r - l + 1];
  15.     return nod(ST[l][j], ST[r - (1 << j) + 1][j]);
  16. }
  17.  
  18. void build(int a[], int lg[], int n) {
  19.     for (int i = 0; i < n; ++i) ST[i][0] = abs(a[i]);
  20.     for (int j = 1; j <= lg[n]; ++j) {
  21.         for (int i = 0; i <= (n - (1 << j)); ++i) {
  22.             ST[i][j] = nod(ST[i][j - 1], ST[i + (1 << (j - 1))][j - 1]);
  23.         }
  24.     }
  25. }
  26.  
  27. int main() {
  28.     int n, k, l, r;
  29.     scanf("%d", &n);
  30.     int a[n];
  31.     lg[1] = 0;
  32.         for (int i = 2; i <= n; ++i) {
  33.                 lg[i] = lg[i / 2] + 1;
  34.         }
  35.     for (int i = 0; i < n; ++i) {
  36.         scanf("%d", &a[i]);
  37.     }
  38.     scanf("%d", &k);
  39.     build(a, lg, n);
  40.     for (int i = 0; i < k; ++i) {
  41.         scanf("%d %d", &l, &r);
  42.                 printf("%d\n", query(l, r, lg));
  43.     }
  44.     return 0;
  45. }
  46.  
  47. ____________________________________________________________________________________________________________________________
  48.  
  49. Наибольший общий делитель подпоследовательности
  50.  
  51. Составьте программу rangegcd.c, вычисляющую наибольший общий делитель на различных интервалах последовательности целых чисел.
  52.  
  53. Формат входных данных
  54. Первая строка, считываемая со стандартного потока ввода, содержит размер последовательности n (0 < n ≤ 300000). Во второй строке перечислены элементы последовательности. Каждый элемент представляет собой целое число, находящееся в диапазоне от -109 до 109. Элементы разделяются пробелами.
  55. Третья строка содержит общее количество запросов m (0 < m ≤ 1000000). Каждая из следующих m строк содержит запрос, который представляет собой два числа l и r, задающие границы интервала, на котором нужно вычислить наименьший общий делитель (0 ≤ l,r < n).
  56. Формат результата работы программы
  57. Для каждого запроса вывести в стандартный поток вывода наименьший общий делитель указанной подпоследовательности.
  58. Пример работы программы
  59.  
  60. Ввод:
  61. 10
  62. -10 -2 5 60 80 100 77 65 33 45
  63. 6
  64. 0 9
  65. 0 1
  66. 2 5
  67. 3 5
  68. 6 8
  69. 8 9
  70. Вывод:
  71. 1
  72. 2
  73. 5
  74. 20
  75. 1
  76. 3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement