codeforces 475D CGCDSSQ ST表+二分

来源:互联网 发布:人事管理数据流程图 编辑:程序博客网 时间:2024/04/18 15:03

点击打开链接链接

CGCDSSQ
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 test(s)
input
32 6 3512346
output
12201
input
710 20 3 15 1000 60 16101234561020601000
output
14022202211
给出一串数字  q个查询

问有几对l r使得从l到r的gcd为x

用线段树会T

ST表 然后二分 

代码如下

#include<cstdio>#include<cstring>#include<algorithm>#include<map>#define MAXN 111111using namespace std;int n,stgcd[MAXN][35],num[MAXN];int prelog2[MAXN];map<int ,long long > ans;int gcd(int a,int b){    if(b==0)return a;    return gcd(b,a%b);}void init(){    prelog2[1]=0;    for(int i=2;i<=n;i++){prelog2[i]=prelog2[i-1];if((1<<prelog2[i]+1)==i)    prelog2[i]++;    }    for(int i=n;i>=1;i--){stgcd[i][0]=num[i];for(int j=1;(i+(1<<j)-1)<=n;j++){    stgcd[i][j]=gcd(stgcd[i][j-1],stgcd[i+(1<<j-1)][j-1]);}    }}int getgcd(int l,int r){    int len=r-l+1;    return gcd(stgcd[l][prelog2[len]],stgcd[r-(1<<prelog2[len])+1][prelog2[len]]);}void solve(){    for(int i=1;i<=n;i++){int ed=i,l,r,m,pos;while(ed<=n){    int xx=getgcd(i,ed);    l=ed,r=n,pos=-1;    while(l<=r){if(r-l<=1){    if(getgcd(i,r)==xx)pos=r;    else if(getgcd(i,l)==xx)pos=l;    break;}m=l+r>>1;if(getgcd(i,m)==xx)    l=m;else r=m;    }    ans[xx]+=pos-ed+1;    ed=pos+1;}    }}int main(){    int q,xx;    scanf("%d",&n);    for(int i=1;i<=n;i++)scanf("%d",&num[i]);    init();    solve();    scanf("%d",&q);    while(q--){scanf("%d",&xx);printf("%I64d\n",ans[xx]);    }    return 0;}


0 0
原创粉丝点击