Description
Given a sequence of integers a1, ..., an and q queries x1, ..., xq on it. For each query xi you have to count the number of pairs (l, r)such that 1 ≤ l ≤ r ≤ n and gcd(al, al + 1, ..., ar) = xi.
is a greatest common divisor of v1, v2, ..., vn,
that is equal to a largest positive integer that divides all vi.
Input
The first line of the input contains integer n, (1 ≤ n ≤ 105), denoting the length of the sequence. The next line contains n space separated integers a1, ..., an, (1 ≤ ai ≤ 109).
The third line of the input contains integer q, (1 ≤ q ≤ 3 × 105), denoting the number of queries. Then follows q lines, each contain an integer xi, (1 ≤ xi ≤ 109).
Output
For each query print the result in a separate line.
Sample Input
3 2 6 3 5 1 2 3 4 6
1 2 2 0 1
7 10 20 3 15 1000 60 16 10 1 2 3 4 5 6 10 20 60 1000
14 0 2 2 2 0 2 2 11
求所有区间的gcd的值,对于以i为右端点的全部gcd的种类一定是log(a[i])级别的,
往这些区间里再加上a[i+1],再把相同的区间合并,就可以保证全部的效率是nlogn了。
顺便一提,HDU5726和这题几乎一模一样,那题我用了线段树,时间上要多一个log
我就说怎么大家都会写,原来cf上有过类似的题目啊。
#include<set> #include<map> #include<ctime> #include<cmath> #include<stack> #include<queue> #include<bitset> #include<cstdio> #include<string> #include<cstring> #include<iostream> #include<algorithm> #include<functional> #define rep(i,j,k) for (int i = j; i <= k; i++) #define per(i,j,k) for (int i = j; i >= k; i--) #define loop(i,j,k) for (int i = j;i != -1; i = k[i]) #define lson x << 1, l, mid #define rson x << 1 | 1, mid + 1, r #define fi first #define se second #define mp(i,j) make_pair(i,j) #define pii pair<int,int> using namespace std; typedef long long LL; const int low(int x) { return x&-x; } const double eps = 1e-4; const int INF = 0x7FFFFFFF; const int mod = 9973; const int N = 3e5 + 10; map<int, LL> M; int n, x; int gcd(int x, int y) { return x%y ? gcd(y, x%y) : y; } int main() { scanf("%d", &n); stack<pii> a, b; rep(i, 1, n) { scanf("%d", &x); a.push(mp(x, 1)); while (!a.empty()) b.push(mp(gcd(a.top().fi, x), a.top().se)), a.pop(); while (!b.empty()) { pii q = b.top(); b.pop(); M[q.fi] += q.se; if (!a.empty() && a.top().fi == q.fi) q.se += a.top().se, a.pop(); a.push(q); } } scanf("%d", &n); while (n--) { scanf("%d", &x); printf("%lld\n", M[x]); } return 0; }