• hdu 5726 GCD 暴力倍增rmq


    GCD/center>

    题目连接:

    http://acm.hdu.edu.cn/showproblem.php?pid=5726

    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

    Hint

    题意

    给你n个数,Q次询问,问你(l,r)区间的gcd是多少,然后再问你整个序列中,有多少子串的gcd和询问的GCD是相同的。

    题解:

    线段树TLE了,应该是我们写丑了……

    然后改成了倍增RMQ才过的。

    考虑gcd这个东西,枚举起点后,他最多log(1e9)种可能,所以我们直接枚举起点,然后暴力二分到每个gcd的区间,然后直接算这个gcd的贡献。

    那么我们的询问就都可以O(1)回答了。

    代码

    #include <bits/stdc++.h>
    #define rep(a,b,c) for(int (a)=(b);(a)<=(c);++(a))
    #define drep(a,b,c) for(int (a)=(b);(a)>=(c);--(a))
    #define pb push_back
    #define mp make_pair
    #define sf scanf
    #define pf printf
    #define two(x) (1<<(x))
    #define clr(x,y) memset((x),(y),sizeof((x)))
    #define dbg(x) cout << #x << "=" << x << endl;
    const int mod = 1e9 + 7;
    int mul(int x,int y){return 1LL*x*y%mod;}
    int qpow(int x , int y){int res=1;while(y){if(y&1) res=mul(res,x) ; y>>=1 ; x=mul(x,x);} return res;}
    inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
    using namespace std;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e5 + 15;
    int N,a[maxn],b[maxn][18],mm[maxn];
    map < int , long long > ha;
    
    void initrmp(int n)
    {
        mm[0]=-1;
        for(int i=1;i<=n;i++){
            mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];
        }
    }
    
    int query(int l,int r){
        int k = mm[r-l+1];
        return __gcd(b[l][k],b[r-(1<<k)+1][k]);
    }
    
    
    int main(int argc,char *argv[]){
        int T=read(),cas=0;
        while(T--){
            ha.clear();
            N=read();
            initrmp(N);
            rep(i,1,N){
                a[i]=read();
                b[i][0]=a[i];
            }
            rep(j,1,17) for(int i = 1 ; i + ( 1 << j ) - 1 <= N ; ++ i) b[i][j]=__gcd( b[i][j-1] , b[i + two(j-1)][j-1] );
            rep(i,1,N){
                int cur = i , gc = a[i];
                while( cur <= N ){
                    int l = cur , r = N;
                    while( l < r ){
                        int mid = l + r + 1 >> 1;
                        if(query(i,mid)==gc) l = mid ;
                        else r = mid - 1;
                    }
                    if(ha.count(gc)) ha[gc] +=(l-cur+1);
                    else ha[gc]=(l-cur+1);
                    cur = l + 1 , gc = __gcd( gc , a[l + 1] );
                }
            }
            int Q=read();
            pf("Case #%d:
    ",++cas);
            while(Q--){
                int l = read(),r=read(),gc=query(l,r);
                pf("%d",gc);
                if(ha.count(gc)) pf(" %I64d
    ",ha[gc]);
                else pf(" 0
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    JAVA 打开文件乱码
    单引号和双引号的区别
    global和$GLOBALS[]的区别
    php统计数组元素个数
    PHP5.3x不再支持ereg和eregi
    discuz论坛diy标签
    网页特效过渡功能
    discuz缓存机制
    php数组中删除元素
    speedphp是个不错的框架
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5687126.html
Copyright © 2020-2023  润新知