HDU 5317 RGCDQ (合数分解+预处理)

题目链接:HDU 5317 RGCDQ

题意:定义函数F(x)为x的不同的素因子且小于等于x的个数。询问[l,r]区间中gcd(F(i),F(j))的最大值。

思路:暴力预处理出全部的合数分解结果。发现F(x)最大也仅仅有7。之后就是暴力求出全部1到7出现次数的前缀和。询问的时候就打到O(1)了。


AC代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAXN 1000010
bool isPrime[MAXN+10];
int Prime[800000+10];
int sum[8][MAXN+10];
int d[MAXN+10];
int cnt=0;
void init(){
    int i,j;
    memset(isPrime,true,sizeof isPrime);
    isPrime[0]=isPrime[1]=false;
    for(i=2;i<=MAXN;i++){
        if(!isPrime[i]) continue;
        Prime[cnt++]=i;
        for(j=i+i;j<=MAXN;j+=i)
            isPrime[j]=false;
    }
}

int slove(int x){
    int i,ans;
    ans=0;
    for(i=0;Prime[i]*Prime[i]<=x && i<cnt;i++){
        if(x%Prime[i]==0){
            while(x%Prime[i]==0){
                x/=Prime[i];
            }
            ans++;
        }
    }
    if(x!=1) ans++;
    return ans;
}

void Pre(){
    init();
    int i,j;
    memset(sum,0,sizeof sum);
    memset(d,0,sizeof d);
    for(i=2;i<=MAXN;i++) {
        d[i]=slove(i);//f函数的值
    }
    for(i=1;i<=7;i++){
        for(j=1;j<=MAXN;j++){
            if(d[j]==i)
                sum[i][j]=sum[i][j-1]+1;
			else sum[i][j]=sum[i][j-1];
            //printf("%d:%d..",j,sum[i][j]);
            //getchar();
        }
    }
}

int gcd(int x,int y){
    if(y==0) return x;
    return gcd(y,x%y);
}
int main(){
    Pre();
    int t,l,r,i,j;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&l,&r);
        int ans=1;
        for(i=1;i<=7;i++){
            for(j=1;j<=7;j++){
                int a=sum[i][r]-sum[i][l-1];
                int b=sum[j][r]-sum[j][l-1];
				if(a==0 || b==0)//表示个数是0说明个数为i或j没有出现
					continue;
                if(i!=j || a>=2){
                    ans=max(ans,gcd(i,j));
                }
            }
        }
        printf("%d\n",ans);
    }
return 0;
}
/*




4 9
1
100 1000
4

213 454
4
112 1111
4


5 1111
4
1111 11111
5
11111 111111
6
111111 999999
6
999991 1000000
3
*/


posted @ 2017-06-07 13:03  jzdwajue  阅读(97)  评论(0编辑  收藏  举报