hdu5317 RGCDQ

来源:互联网 发布:世界征服者3mac 编辑:程序博客网 时间:2024/05/16 09:18

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
22 33 5
 

Sample Output
11

题意:

给定范围(L,R),f(x)代表x的素因数个数,相同的素数算一个,现在求L-R范围内,GCD(F(i),F(j))(Li<jR)

的最大值。


解答:

因为2*3*5*7*11*13*17=510510,再乘一个就超过R范围,所以函数的值最多为7.

所以统计7个前缀和,也就是前i个位置中有几个f[i]==j的数,然后利用前缀和我们就能够得到每个区间各个数的个数,然后枚举所有情况

1.当i属于3~7的时候,f[i]的个数>=2的时候,ans == i

用get ( i ) 表示sum[i][r]-sum[i][l-1]

2.当get(3)>0&&get(6)>0,那么ans == 3

3.当get(2)> 1 || ( get(2) > 0  && get(4) > 0 ) 的时候,ans == 2

其余情况ans == 1



代码:


#include <algorithm>#include <cstdio>#define MAX 1000007using namespace std;int maxPrime[MAX];int f[MAX];int sum[10][MAX];void init ( ){    memset ( maxPrime , -1 , sizeof ( maxPrime ));    for ( int i = 2 ; i < MAX ; i++ )    {        if (~maxPrime[i]) continue;        for ( int j = 1 , t = i ; t < MAX ; j++ , t+=i )            maxPrime[t] = i;    }}void solve ( ){    f[2] = 1;f[1] = 0;    for ( int i = 3 ; i < MAX ; i++ )    {        int x = maxPrime[i];        int y = i;        while ( y%x == 0 )            y /= x;        f[i] = f[y] + 1;    }    /*for (int i = 1 ; i <= 20 ; i++ )        printf ( "%d " , f[i] );    puts("");*/    for ( int i = 0 ; i < 8 ; i++ )        sum[i][0] = 0;    for ( int i = 1;i < MAX ; i++ )    {        sum[f[i]][i] = sum[f[i]][i-1]+1;    }    for ( int i = 0 ; i < 8 ; i++ )        for ( int j = 1 ; j < MAX ; j++ )            sum[i][j] += sum[i][j-1];}int t,l,r;int get ( int i ){    return sum[i][r] - sum[i][l-1];}int main ( ){    init ( );    solve ();    scanf ( "%d" , &t );    while ( t-- )    {        scanf (  "%d%d" , &l , &r );        int ans = 1;        for ( int i = 7 ; i >= 3 ; i-- )            if ( get(i) > 1 )            {                ans = i;                break;            }        if ( get(6) > 0 && get(3) > 0 )            ans = max ( ans , 3 );        if ( get(4) > 0 && get ( 2 ) > 0 )            ans = max ( ans , 2 );        if ( get(2) > 1 )            ans = max ( ans , 2 );        printf ( "%d\n" , ans );    }}
另一种解法;

#include<iostream>#include<cstdio>#include<cstring>#define MAXN 1000010using namespace std;int isp[MAXN]; int sum[MAXN];//每个数有多少个素数因子int dp[MAXN][10];//前i个数里有j个素数因子的数有几个int a[10];void Prime(){    memset(isp,0,sizeof(isp));    memset(sum,0,sizeof(sum));    for(int i=2;i<MAXN;i++)        {            if(!isp[i])            {                for(int j=i;j<MAXN;j+=i)                {                    if(i!=j)                       isp[j]=1;                    sum[j]++;                }            }        }}int gcd(int a,int b){    if(b==0)        return a;    return gcd(b,a%b);}int main(){    int T;    Prime();    memset(dp,0,sizeof(dp));    for(int i=1;i<MAXN;i++)    {        for(int j=1;j<=7;j++)        {            dp[i][j]=dp[i-1][j];        }        dp[i][sum[i]]++;    }    scanf("%d",&T);    while(T--)    {        int l,r;        scanf("%d%d",&l,&r);        int ans=1;        for(int i=2;i<=7;i++)        {            a[i]=(dp[r][i]-dp[l-1][i])>1?i:1;            if(dp[r][i]-dp[l-1][i]>=2)            {                ans=max(ans,i);            }            for(int j=2;j<i;j++)            {                ans=max(ans,gcd(a[i],a[j]));            }        }       cout<<ans<<endl;    }    return 0;}


害羞

0 0
原创粉丝点击