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

来源:互联网 发布:ajax请求php 编辑:程序博客网 时间:2024/04/29 06:16

题目链接: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 1000010bool 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 91100 10004213 4544112 111145 111141111 11111511111 1111116111111 9999996999991 10000003*/


1 0