• HDU 5726 GCD(ST&RMQ)


    题目链接 GCD

    先ST倍增预处理,f[i][j]表示从i开始(包含第i个数)的连续2^j个数的最大公约数。

    这样就可以在O(1)内询问得到a[l]到a[r]之间的所有数的最大公约数的值。

    然后对于每个数a[i],以这个数为开头的所有子序列的最大公约数的不同值不会超过30个。

    而且不同的值是满足单调递减的。

    那么就可以二分查找然后把对应值的个数塞进map。

    时间复杂度O(Nlog(N))

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i,a,b)        for(int i(a); i <= (b); ++i)
    #define LL            long long
    
    const int N    =    100000        +    10;
    const int A    =    30        +    1;
    
    map <int, LL> mp;
    int a[N];
    int T;
    int n, m;
    int l, r;
    int f[N][A];
    int gcd(int a, int b){return b? gcd(b, a % b) : a;}
    
    inline int Solve(int l, int r){
        int k = (int)log2((double)(r - l + 1));
        return gcd(f[l][k], f[r - (1 << k) + 1][k]);    
    }
    
    void Work(){
        rep(i, 1, n) f[i][0] = a[i];
        rep(j, 1, 17) rep(i, 1, n) if ((i + (1 << j) - 1) <= n) f[i][j] =gcd(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
    }
    
    void setTable(){
        mp.clear();
        rep(i, 1, n){
            int g = f[i][0], j = i;
            while (j <= n){
                int l = j, r = n;
                while (l < r){
                    int mid = (l + r + 1) >> 1;
                    if (Solve(l, mid) == g) l = mid; else r = mid - 1;
                }
                mp[g] += l - j + 1;
                j = l + 1;
                g = Solve(i, j);
            }
        }
    }
    int main(){
    
        scanf("%d", &T);
        rep(Case, 1, T){
            printf("Case #%d:
    ", Case);
            scanf("%d", &n);
            rep(i, 1, n) scanf("%d", a + i);
            Work();
            setTable();
            scanf("%d", &m);
            while (m--){
                scanf("%d%d", &l, &r);
                int g = Solve(l, r);
                printf("%d %lld
    ", g, mp[g]);
            }
        }
    
        return 0;
        
    }
    
  • 相关阅读:
    站立会议(二)
    站立会议(一)
    买书优惠问题
    软件的NABCD----安装部分
    你的灯亮着吗读书笔记(一)
    软件工程概论---环状二维数组最大子数组和
    梦断代码读书笔记(三)
    梦断代码读书笔记(二)
    课程作业3.10
    软件工程作业提交3.06
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6720256.html
Copyright © 2020-2023  润新知