2015 Multi-University Training Contest 8 The sum of gcd

来源:互联网 发布:苹果手机网络信号差 编辑:程序博客网 时间:2024/05/12 16:45

The sum of gcd

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1156    Accepted Submission(s): 508


Problem Description
You have an array A,the length of A is n
Let f(l,r)=ri=lrj=igcd(ai,ai+1....aj)
 

Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
First line has one integers n
Second line has n integers Ai
Third line has one integers Q,the number of questions
Next there are Q lines,each line has two integers l,r
1T3
1n,Q104
1ai109
1l<rn
 

Output
For each question,you need to print f(l,r)
 

Sample Input
251 2 3 4 531 32 31 444 2 6 931 32 42 3
 

Sample Output
9616182310

【题意】如题所示。

【解题方法】gcd预处理套莫队算法。大牛博客http://blog.csdn.net/u014800748/article/details/47680899

【AC 代码】

////Created by just_sort 2016/9/12 16:50//Copyright (c) 2016 just_sort.All Rights Reserved//#include <set>#include <map>#include <queue>#include <stack>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;const int maxn = 1e4+7;int n,m,block;int a[maxn];LL ans[maxn];struct Q{    int l,r,id;    bool operator<(const Q &rhs) const{        if(l/block==rhs.l/block) return r<rhs.r;        return l/block<rhs.l/block;    }}q[maxn];struct node{int id;int g;};vector <node> vl[maxn],vr[maxn];void init(){    for(int i=1; i<=n; i++){        if(i==1) vl[i].push_back(node{i,a[i]});        else{            int curg=a[i];            int L=i;            for(auto &it:vl[i-1]){                int g = __gcd(it.g,curg);                if(g!=curg) vl[i].push_back(node{L,curg});                curg=g,L=it.id;            }            vl[i].push_back(node{L,curg});        }    }    for(int i=n; i>=1; i--){        if(i==n) vr[i].push_back(node{i,a[i]});        else{            int curg=a[i];            int R=i;            for(auto &it:vr[i+1]){                int g = __gcd(it.g,curg);                if(g!=curg) vr[i].push_back(node{R,curg});                curg=g,R=it.id;            }            vr[i].push_back(node{R,curg});        }    }}LL cal(int op,int L,int R){    LL ret = 0;    if(op==0){        int tr = R;        for(auto &it : vl[R]){            if(it.id>=L){                ret += 1LL*(tr-it.id+1)*it.g;                tr = it.id-1;            }else{                ret += 1LL*(tr-L+1)*it.g;                break;            }        }    }else{        int tl = L;        for(auto &it : vr[L]){            if(it.id<=R){                ret += 1LL*(it.id-tl+1)*it.g;                tl = it.id+1;            }else{                ret += 1LL*(R-tl+1)*it.g;                break;            }        }    }    return ret;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for(int i=1; i<=n; i++) vl[i].clear(),vr[i].clear();        for(int i=1; i<=n; i++) scanf("%d",&a[i]);        init();        scanf("%d",&m);        for(int i=0; i<m; i++){            scanf("%d%d",&q[i].l,&q[i].r);            q[i].id=i;        }        block = (sqrt(n));        sort(q,q+m);        int L=1,R=0;        LL ret = 0;        for(int i=0; i<m; i++){            while(R<q[i].r){                R++;                ret += cal(0,L,R);            }            while(R>q[i].r){                ret -= cal(0,L,R);                R--;            }            while(L>q[i].l){                L--;                ret += cal(1,L,R);            }            while(L<q[i].l){                ret -= cal(1,L,R);                L++;            }            ans[q[i].id] = ret;        }        for(int i=0; i<m; i++){            printf("%I64d\n",ans[i]);        }    }    return 0;}


0 0
原创粉丝点击