zoukankan      html  css  js  c++  java
  • HDU 5726 GCD(DP)

    【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=5726

     

    【题目大意】

      给出数列An,对于询问的区间【L,R】,求出区间内数的GCD值,并且求出GCD值与其相等的区间总数

     

    【题解】

      首先,固定一个区间的右端点,利用GCD的递减性质,可以求出GCD相等的区间左端点的范围,将其范围的左右端点保存下来,同时,对于每个新产生的区间,以其GCD值为下标的MAP值+1,最后对于每个询问,在其右端点保存的范围中查找,获得其GCD值,同时在MAP中获取该GCD值对应的区间总数,输出即可。

     

    【代码】

    #include <map>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    map<int,long long> M;
    const int N=100005;
    int Gcd,n,l[N],v[N],len[N],T,j,q,L,R,Cas,a[N];
    struct data{int l,v;}p[N][50];
    int gcd(int x,int y){return __gcd(x,y);}
    int main(){
        scanf("%d",&T);
        while(T--){
            printf("Case #%d:
    ",++Cas);
            M.clear();
            scanf("%d",&n);
            memset(len,0,sizeof(len));
            for(int i=1;i<=n;i++)scanf("%d",&a[i]);
            for(int i=1;i<=n;i++)for(v[i]=a[i],j=l[i]=i;j;j=l[j]-1){
                v[j]=gcd(v[j],a[i]);
                while(l[j]>1&&gcd(a[i],v[l[j]-1])==gcd(a[i],v[j]))l[j]=l[l[j]-1];
                p[i][len[i]].l=l[j];p[i][len[i]++].v=v[j];
                M[v[j]]+=(j-l[j]+1);
            }scanf("%d",&q);
            while(q--){
                scanf("%d%d",&L,&R);
                for(int i=0;i<len[R];i++){
                    if(L>=p[R][i].l){Gcd=p[R][i].v;break;}
                }printf("%d %lld
    ",Gcd,M[Gcd]);
            }
        }return 0;
    }
    

      

  • 相关阅读:
    MYSQL语法篇之:“建”、“增”
    MYSQL数据库管理系统
    数据库管理系统
    初识数据库
    JDK/JRE/JVM的区别与联系
    计算机语言的发展史
    Java的三大版本
    Java的特性和优势
    初识Java
    补充:DOS命令
  • 原文地址:https://www.cnblogs.com/forever97/p/hdu5726.html
Copyright © 2011-2022 走看看