Title Description
Given row \ (n-\) positive integers \ (A [. 1] .. A [n-] \) .
\ (m \) times query, given a query each time interval \ ([L, R & lt] \) , output \ (a [L] .. a [R] \) is the greatest common factor.
Input Format
The first line of two integers \ (n-, m \) .
The second row represents n integers \ (A [. 1] .. A [n] \) .
The following \ (m \) rows, each row \ (2 \) integer showing about endpoint interrogation interval.
Ensure that the input data is valid.
Output Format
Co m lines, each line represents an answer to the inquiry.
Sample input and output
Input # 1
5 3
4 12 3 6 7
1 3
2 3
5 5
Output # 1
1
3
7
Description / Tips
For 30% of the data, \ (n-<= 100, m <= 10 \)
For 60% of the data, \ (m <= 1000 \)
To 100% of the data, \ (. 1 <= n-<= 1000,1 <= m <= 1, 000,000 \)
0 < 数字大小 <= 1,000,000,000
answer:
There is provided a segment tree structure pointer written here:
Solving the problem, you must first know \ (gcd \) the method for finding, seen from the Euclidean algorithm:
int gcd(int x, int y) { return y == 0 ? x : gcd(y, x % y); }
Secondly, \ (GCD \) satisfies section additivity, namely:
\ [GCD (L, R & lt) = GCD (GCD (L, K), GCD (K +. 1, R & lt)), K \ in [L, R & lt ] \]
segment tree maintenance can be directly ...
code:
#include <iostream>
#include <cstdio>
using namespace std;
int read() {
int x = 0, f = 1; char ch;
while(! isdigit(ch = getchar())) (ch == '-') && (f = -f);
for(x = ch^48; isdigit(ch = getchar()); x = (x<<3) + (x<<1) + (ch^48));
return x * f;
}
int n, m;
inline int gcdd(int x, int y) { return y == 0 ? x : gcdd(y, x % y); }
struct Segment {
struct node {
int l, r, gc;
node* ch[2];
node(int l, int r, int gc) : l(l), r(r), gc(gc) {}
inline int mid() { return (l + r) >> 1; }
inline void up() { gc = gcdd(ch[0]->gc, ch[1]->gc); }
} *root;
void build(node *&o, int l, int r) {
o = new node (l, r, 0);
if(l == r) { o->gc = read(); return; }
build(o->ch[0], l, o->mid());
build(o->ch[1], o->mid()+1, r);
o->up();
}
int query(node *o, int l, int r) {
if(l <= o->l && o->r <= r) return o->gc;
int res = 0;
if(o->mid() >= l) res = query(o->ch[0], l, r);
if(o->mid() < r) res = gcdd(res, query(o->ch[1], l, r));
return res;
}
} tr;
int main() {
n = read(); m = read();
tr.build(tr.root, 1, n);
for(int i = 1, l, r; i <= m; ++ i) {
l = read(); r = read();
printf("%d\n", tr.query(tr.root, l, r));
}
return 0;
}