codeforces 475D. CGCDSSQ

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+10;
inline void read(int &x){
    x=0;char ch=getchar();
    while(ch<'0'||ch>'9')   ch=getchar();
    while(!(ch<'0'||ch>'9'))  x=x*10+ch-48,ch=getchar();
}
int n,m;
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
std::map<int ,ll > query;
int a[N],lg[N],bin[20];
int f[20][N];
inline int ques(int l,int r){
    if(r==n+1)  return 0;
    int t=lg[r-l+1];
    return gcd(f[t][l],f[t][r-bin[t]+1]);
}
inline void init(){
    lg[0]=-1;for(int i=1;i<=n;i++)lg[i]=lg[i>>1]+1;
    bin[0]=1;for(int i=1;i<=18;i++)  bin[i]=bin[i-1]<<1;
    for(int i=1;i<=n;i++)   f[0][i]=a[i];
    for(int i=1;i<=lg[n];i++)
        for(int j=1;j+bin[i]<=n+1;j++){
            f[i][j]=gcd(f[i-1][j],f[i-1][j+bin[i-1]]);
        }
}
inline  int find(int x,int l,int op){
    int r=n+1;
    while(l<r-1){
        int mid=l+r>>1;
        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+1){
        last=now;
        now=find(t,now,x);
        if(query[t])query[t]+=now-last+1;
        now++;t=ques(x,now);
    }
}
int x[N];
int main(){
    read(n);
    for(int i=1;i<=n;i++)   read(a[i]);
    read(m);
    init();
    for(int i=1;i<=m;i++){
        read(x[i]);
        query[x[i]]=1;
    }
    for(int i=1;i<=n;i++)solve(i);
    for(int i=1;i<=m;i++)
        printf("%I64d
",query[x[i]]-1);
  //while(1);
}
原文地址:https://www.cnblogs.com/Troywar/p/7233270.html