P1890 gcd区间 - st表
st表细节多。。。
用线段树维护也行,会慢一点
最大公约数这个东西区间上是“可加”的
所以可以很方便地合并出区间gcd
注意位运算优先级低,多加括号
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const int MAXN = 1000000 + 10;
int n,m,st[MAXN][25],a[MAXN];
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a%b);
}
void init_st() {
int mt = log(n) / log(2) + 1;
for(int k=1; k<=mt; k++) {
for(int i=1; i+(1<<k)-1<=n; i++) {
st[i][k] = gcd(st[i][k-1], st[i+(1<<k-1)][k-1]);
}
}
}
int query(int l, int r) {
int kt = log(r-l+1) / log(2);
return gcd(st[l][kt], st[r-(1<<kt)+1][kt]);
}
int main() {
scanf("%d%d", &n, &m);
for(int i=1; i<=n; i++) {
scanf("%d", &a[i]);
st[i][0] = a[i];
}
init_st();
for(int i=1; i<=m; i++) {
int l, r;
scanf("%d%d", &l, &r);
printf("%d\n", query(l, r));
}
return 0;
}