• hdu 5726(二分)


    GCD
    
    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 1233    Accepted Submission(s): 382
    
    
    Problem Description
    Give you a sequence of N(N≤100,000) integers : a1,...,an(0<ai≤1000,000,000). There are Q(Q≤100,000) queries. For each query l,r you have to calculate gcd(al,,al+1,...,ar) and count the number of pairs(l′,r′)(1≤l<r≤N)such that gcd(al′,al′+1,...,ar′) equal gcd(al,al+1,...,ar).
     
    
    Input
    The first line of input contains a number T, which stands for the number of test cases you need to solve.
    
    The first line of each case contains a number N, denoting the number of integers.
    
    The second line contains N integers, a1,...,an(0<ai≤1000,000,000).
    
    The third line contains a number Q, denoting the number of queries.
    
    For the next Q lines, i-th line contains two number , stand for the li,ri, stand for the i-th queries.
     
    
    Output
    For each case, you need to output “Case #:t” at the beginning.(with quotes, t means the number of the test case, begin from 1).
    
    For each query, you need to output the two numbers in a line. The first number stands for gcd(al,al+1,...,ar) and the second number stands for the number of pairs(l′,r′) such that gcd(al′,al′+1,...,ar′) equal gcd(al,al+1,...,ar).
     
    
    Sample Input
    1
    5
    1 2 4 6 7
    4
    1 5
    2 4
    3 4
    4 4
     
    
    Sample Output
    Case #1:
    1 8
    2 4
    2 4
    6 1
    /*
    难点在于计数,关键要发现gcd的递减性
    对于1到n的(l,r)
    对于固定的l
    gcd(l,r)>=gcd(l,r+1)
    对于固定的r
    gcd(l,r)<=gcd(l+1,r)
    因此可以不用逐一地进行计数
    方法为:
    枚举每一个左区间,对满足gcd(l,ri)的右区间进行二分查找
    跳跃着进行计数
    */
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <iostream>
    #include <map>
    #include <vector>
    #define scan1(x)     scanf("%d",&x)
    #define scan2(x,y)   scanf("%d%d",&x,&y)
    #define scan3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    using namespace std;
    typedef long long LL;
    const int inf=0x3f3f3f3f;
    const int Max=1e6+10;
    int dp[Max][30];
    map<int,LL> vis;
    int A[Max];
    int gcd(int x,int y)
    {
        if(x<y) swap(x,y);
        return (y==0?x:gcd(y,x%y));
    }
    void RMQ_init(int n)
    {
        for(int i=1; i<=n; i++) dp[i][0]=A[i];
        for(int j=1; (1<<j)<=n; j++)
        {
            for(int i=1; i+(1<<j)-1<=n; i++)
            {
                dp[i][j]=gcd(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
            }
        }
    }
    int RMQ(int l,int r)
    {
        int k=0;
        while((1<<(k+1))<=r-l+1) k++;
        return gcd(dp[l][k],dp[r-(1<<k)+1][k]);
    }
    void Init()
    {
       vis.clear();
    }
    int L[Max],R[Max];
    int main()
    {
        int T,ca=1;
        for(scan1(T); T; T--)
        {
            int n,m,num;
            scan1(n);
            for(int i=1; i<=n; i++) scan1(A[i]);
            RMQ_init(n);
            Init();
            scan1(m);
            for(int i=1; i<=m; i++)
            {
                scan2(L[i],R[i]);
                num=RMQ(L[i],R[i]);
                vis.insert(make_pair(num,0));
            }
            int l,r,mid,d1,d2,ans,nex;
            for(int i=1; i<=n; i++)
            {
                nex=i;
                while(nex<=n)
                {
                    d1=RMQ(i,nex);
                    l=nex;r=n;
                    while(l<=r)
                    {
                        mid=(l+r)>>1;
                        d2=RMQ(i,mid);
                        if(d2>=d1) l=mid+1,ans=mid;
                        else r=mid-1;
                    }
                    if(vis.find(d1)!=vis.end())
                    vis[d1]+=(ans-nex)+1;
                    nex=r+1;
                }
            }
            printf("Case #%d:
    ",ca++);
            for(int i=1; i<=m; i++)
            {
                ans=RMQ(L[i],R[i]);
                printf("%d %lld
    ",ans,vis[ans]);
            }
        }
        return 0;
    }
  • 相关阅读:
    WordPress让文本小工具支持简码
    修改WordPress后台登录地址,提高安全性
    WordPress用键盘左右方向键来查看上一篇和下一篇文章
    Git 补丁操作
    Git 标签操作
    Git 修正错误
    Git 删除操作
    Git 重命名操作
    Git 移动操作
    Git 藏匿操作
  • 原文地址:https://www.cnblogs.com/zsyacm666666/p/5689066.html
Copyright © 2020-2023  润新知