hdu5317 RGCDQ 统计

//    hdu5317 RGCDQ
//
//    题目大意:
//
//    给定一个闭区间[l,r],定义f(x)是x的不同的质因子的个数
//    比方: 12 = 2 * 2 * 3,是两种。所以f(x) = 2,问max GCD(f[i],f[j])
//    i,j在[l,r]范围内,而且i!=j.
//
//    解题思路:
//
//    首先伟大的W神发现了一个规律。就是小于等于1e6不同的素因子个数不会超过7个
//    这样。我们就行统计出在1到i这个区间内,1-7各出现了多少次。最后R-(L-1)>=2
//    说明出现了两次以上,那么最大公约数就是此时的i啦。统计一下,然后O(1)求值。
//
//    感悟:
//
//    这道题,開始想复杂了,还和大神们一起讨论线段树怎么做。然后发现当时过的队伍好多,
//    就再没往这方面想,还是J大神最后秒了这题。确实挺巧妙的。当时的我就在卖萌。哎,
//    自己不会的千千万。不,应该说我就不会什么。继续加油吧!fighting!
//
//    非常奇怪的一点是在进行埃式筛法的时候開始将isp置为0或者置为1,所花费的时间天差地别,
//    后者TLE了n发。改过来之后1100多ms过了,这里实在想不通,假设有大神可以解答我的疑惑
//    小子定当不胜感激

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <vector>
#define For(i,x,y) for (int i = (x) ;i < (y) ;i ++)
using namespace std;

const int MAX_N = 1000006;
int f[MAX_N];
bool isp[MAX_N];
int p[MAX_N];
int sum[MAX_N][10];
int l,r;
int cnt;
inline void init(){
    cnt = 0;
    memset(isp,0,sizeof(isp));
    isp[0] = isp[1] = 0;

    for (int i=2;i<=MAX_N;i++){
        if (!isp[i]){
            p[cnt++] = i;
            for (long long j = (long long) i  * i;j < MAX_N;j+=i){
                isp[j] = 1;
            }
        }
    }
    f[1] = 0;
    for (int i=2;i< MAX_N;i++){
        int x = i;
        f[i] = 0;
        for (int j=0;j<cnt && isp[x]==1;j++){
            if (x%p[j]==0){
                f[i]++;
                while(x%p[j]==0){
                    x/=p[j];
                }
            }
        }
        if (x>1)
            f[i]++;
    }

    for (int i=1;i<8;i++)
        sum[1][i] = 0;


    for (int i=2;i<=MAX_N;i++){
        for (int j=1;j<8;j++)
            sum[i][j] = sum[i-1][j];
        for (int j=1;j<8;j++){
            if (f[i]%j==0){
                sum[i][j]++;
            }
        }
    }
}





inline void solve(){
    scanf("%d%d",&l,&r);
    int mx = 0;
    for (int i=8;i>=1;i--){
        if (sum[r][i] - sum[l-1][i] >= 2){
            mx = i;
            break;
        }
    }
    printf("%d
",mx);

}

int main(){
    int t;
    init();
    //freopen("1.txt","r",stdin);
    scanf("%d",&t);
    while(t--){

        solve();
    }
}

原文地址:https://www.cnblogs.com/tlnshuju/p/7159761.html