codeforces 475D. CGCDSSQ

时间:2022-12-18 20:15:56

D. CGCDSSQ

                                  time limit per test 2 seconds

memory limit per test 256 megabytes

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.

Examples

input

3
2 6 3
5
1
2
3
4
6

output

1
2
2
0
1

input

7
10 20 3 15 1000 60 16
10
1
2
3
4
5
6
10
20
60
1000

output

14
0
2
2
2
0
2
2
1
1

题目大意:

一个长度为n的a数列,q次询问。每次询问一个数值x,求解有多少个[l,r](1<=l<=r<=n)满足Gcd(a[l],a[l+1],……,a[r])为x。

其中n<=1e5,q<=3e5,任意x,a[i]满足1<=x,a[i]<=1e9;

题解:

显然,对于每个询问我们都不得不枚举每个左端点,然后查询满足条件的右端点区间,然而在线超时,所以我们可以把询问用map记录,离线处理。又数组为静态,我们只需要静态维护一下区间最大公约数。同时把统计得到的每个询问结果累加即可。

#include<cstdio>
#include<map>
typedef long long ll;
const int N=(int)1e6+;
inline void read(int &x){
x=;char ch=getchar();
while(ch<''||ch>'') ch=getchar();
while(!(ch<''||ch>'')) x=x*+ch-,ch=getchar();
}
int n,m;
int gcd(int x,int y){return y==?x:gcd(y,x%y);}
std::map<int ,ll > query;
int a[N],lg[N],bin[];
int f[][N];
inline int ques(int l,int r){
if(r==n+) return ;
int t=lg[r-l+];
return gcd(f[t][l],f[t][r-bin[t]+]);
}
inline void init(){
lg[]=-;for(int i=;i<=n;i++)lg[i]=lg[i>>]+;
bin[]=;for(int i=;i<=;i++) bin[i]=bin[i-]<<;
for(int i=;i<=n;i++) f[][i]=a[i];
for(int i=;i<=lg[n];i++)
for(int j=;j+bin[i]<=n+;j++){
f[i][j]=gcd(f[i-][j],f[i-][j+bin[i-]]);
}
}
inline int find(int x,int l,int op){
int r=n+;
while(l<r-){
int mid=l+r>>;
if(ques(op,mid)!=x) r=mid;
else l=mid;
}
return l;
}
inline void solve(int x){
int t=a[x],now=x;
int last;
while(now!=n+){
last=now;
now=find(t,now,x);
if(query[t])query[t]+=now-last+;
now++;t=ques(x,now);
}
}
int x[N];
int main(){
read(n);
for(int i=;i<=n;i++) read(a[i]);
read(m);
init();
for(int i=;i<=m;i++){
read(x[i]);
query[x[i]]=;
}
for(int i=;i<=n;i++)solve(i);
for(int i=;i<=m;i++)
printf("%I64d\n",query[x[i]]-);
//while(1);
}