zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU 5317 RGCDQ (数论)

    Problem Description
    Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and more interesting things about GCD. Today He comes up with Range Greatest Common Divisor Query (RGCDQ). What’s RGCDQ? Please let me explain it to you gradually. For a positive integer x, F(x) indicates the number of kind of prime factor of x. For example F(2)=1. F(10)=2, because 10=2*5. F(12)=2, because 12=2*2*3, there are two kinds of prime factor. For each query, we will get an interval [L, R], Hdu wants to know maxGCD(F(i),F(j)) (Li<jR)
     
    Input
    There are multiple queries. In the first line of the input file there is an integer T indicates the number of queries.
    In the next T lines, each line contains L, R which is mentioned above.

    All input items are integers.
    1<= T <= 1000000
    2<=L < R<=1000000
     
    Output
    For each query,output the answer in a single line.
    See the sample for more details.
     
    Sample Input
    2
    2 3
    3 5
     
    Sample Output
    1
    1

    这个题目比较巧妙。

    f(i)求的是i的素数因子个数。

    首先需要处理因子个数。这个方法很多。

    其实对于一个i来说,由于i最大是1000000,然而当2*3*5*7.....*17这时是最大能在这个范围的。其他数的素数因子数目必然小于这个。也就是f(i)最大是7。

    这样只需要查询L到R区间内f(i)分别为1, 2, 3, 4, 5, 6, 7的个数,然后暴力枚举gcd的最大值就可以了。

    当时人比较二,区间求和直接上了线段树,然后MLE了,然后换成树状数组才AC。。。。

    赛后经人提醒才发现,这个完全没有点修改操作,根本不需要使用上述工具。直接用sum数组保存前缀和就可以。然后sum[j] - sum[i-1]就是[i, j]区间的和了。。。

    不管怎样第一次使用树状数组,还是附上代码。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <algorithm>
    #define LL long long
    
    using namespace std;
    
    //GCD
    //求最大公约数
    //O(logn)
    int gcd(int a, int b)
    {
        if (b == 0)
        return a;
        else
        return gcd(b, a%b);
    }
    
    const int maxN = 1000001;
    
    char f[maxN];
    bool b[maxN];
    int L, R;
    
    struct Val
    {
        int v[8];
    
        Val()
        {
            memset(v, 0, sizeof(v));
        }
        Val operator+(Val x)
        {
            Val ans;
            for (int i = 1; i <= 7; ++i)
                ans.v[i] = x.v[i] + v[i];
            return ans;
        }
        Val operator-(Val x)
        {
            Val ans;
            for (int i = 1; i <= 7; ++i)
                ans.v[i] = v[i] - x.v[i];
            return ans;
        }
    };
    
    Val d[maxN];
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    void add(int pos,Val pls)
    {
        while(pos <= maxN)//x最大是N
        {
            d[pos] = d[pos] + pls;
            pos += lowbit(pos);
        }
    }
    
    Val sum(int to)
    {
        Val s;
        while(to > 0)
        {
            s = s + d[to];
            to -= lowbit(to);
        }
        return s;
    }
    
    Val query(int from, int to)
    {
        return sum(to) - sum(from - 1);
    }
    
    void init()
    {
        int m = 1000000;
        memset(f,0,sizeof(f));
        memset(b,0,sizeof(b));
        for (int i = 2; i <= m; i++)
        {
            if (!b[i])
                for(int j = i; j <= m; j = j+i)
                {
                    b[j] = 1;
                    f[j]++;
                }
        }
    
        for (int i = 2; i <= m; ++i)
        {
            Val tmp;
            tmp.v[f[i]] = 1;
            add(i, tmp);
        }
    }
    
    void work()
    {
        Val p = query(L, R);
        int ans = 0;
        for (int i = 1; i <= 7; ++i)
        {
            if (!p.v[i])
                continue;
            p.v[i]--;
            for (int j = i; j <= 7; ++j)
            {
                if (!p.v[j])
                    continue;
                ans = max(ans, gcd(i, j));
            }
            p.v[i]++;
        }
        printf("%d
    ", ans);
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        init();
        int T;
        scanf("%d", &T);
        for (int times = 0; times < T; ++times)
        {
            scanf("%d%d", &L, &R);
            work();
        }
        return 0;
    }
  • 相关阅读:
    十分简单的宏病毒
    爬虫入门六 总结 资料 与Scrapy实例-bibibili番剧信息
    爬虫入门五 gooseeker
    爬虫入门四 re
    爬虫入门三 scrapy
    爬虫入门二 beautifulsoup
    爬虫入门一 基础知识 以及request
    腾讯游戏策划实习面经
    网络安全实验合集
    HTML5总结
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4684212.html
Copyright © 2011-2022 走看看