HDU 5317(2015多校第三場1002)

RGCDQ

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1320    Accepted Submission(s): 573


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
 

題目大意:
給定L,R,求MAX( gcd ( f[i] , f[j] ) ) L<=i,j<=R
而 f(x)的值爲 x的不同素數因子的個數 其中x<=1000000.
因此我們可以知道,f(x) 最大爲 7 。 (2*3*5*7*11*13*17即等於510510)
因此我們可知答案只可能爲 1-7中的數字
我們只要知道了在L,R中1-7中的數字分別出現了幾次,我們便能求出最大的gcd值。
這個則可以用類似求前綴和的方法進行一次預處理
f(x)則可以用素數的篩選法來求解。(比賽一開始時錯誤的估計了該方法的時間複雜度,導致一開始的時候愣是不敢下手。。。。。。。。)

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <sstream>
#define PI acos(-1.0)
#define eps 1e-8
#define f 1000010
const int  inf =  (1<<30) - 10;
using namespace std;

int s[f], p;
int num[f];
int dp[f][8];

void get_prime()
{
	int i,j,n,m,s1,s2,a,b;
	s[1]=2;
	s[2]=3;
	m=2;
	for(i=6;i<f;i=i+6)
	{
		a=i-1;
		b=i+1;
		s1=1;
		s2=1;
		n=(int)sqrt(m);
		for(j=1;j<=n+1;j++)
			if(a%s[j]==0){s1=0;break;}
		for(j=1;j<=n+1;j++)
			if(b%s[j]==0){s2=0;break;}
		if(s1!=0){m++;s[m]=a;}
		if(s2!=0){m++;s[m]=b;}
	}
	p = m;
}

void init(){
    memset(num,0,sizeof(num));
    memset(dp,0,sizeof(dp));
    for(int i = 1;i <= p; ++i){
        for(int j = 1;j*s[i] <= 1000000; ++j){
            num[j*s[i]]++;
        }
    }
    for(int i = 2;i <= 1000000; ++i){
        for(int j = 1;j <= 7; ++j){
            dp[i][j] = dp[i-1][j];
        }
        dp[i][num[i]]++;
    }
}

int main(){
    //freopen("input.txt","r",stdin);
    get_prime();
    init();
    int T;
    cin>>T;
    int l, r;
    while(T--){
        scanf("%d %d",&l,&r);
        int knum[8];
        for(int i = 1;i <= 7; ++i){
            knum[i] = dp[r][i] - dp[l-1][i];
        }
        if(knum[7] >= 2){
            printf("7\n");
        }else if(knum[6]>=2){
            printf("6\n");
        }else if(knum[5]>=2){
            printf("5\n");
        }else if(knum[4]>=2){
            printf("4\n");
        }else if(knum[3]>=2){
            printf("3\n");
        }else if(knum[6] && knum[3]){
            printf("3\n");
        }else if(knum[2]>=2){
            printf("2\n");
        }else if(knum[6] && knum[2]){
            printf("2\n");
        }else if(knum[4] && knum[2]){
            printf("2\n");
        }else{
            printf("1\n");
        }
    }
    return 0;
}


如有BUG,請大家務必指出,不勝感激~

聯繫方式:[email protected]
發佈了36 篇原創文章 · 獲贊 17 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章