2 2 3 3 5
11
题意:定义了一个函数F(x),表示x这个数的不同素数因数的个数,然后给你一个区间[L,R],问你任意区间内不同的两个数的最大公约数是多少,这里要发现1000000范围内的最大不同素数因数个数是7,所以用dp[i][j]保存从1到i这i个数不同素数因数的个数。这里先预处理1~1000000的数的不同素数因数的个数,可以用普通素数筛法(这里线性筛法好像不能用,因为线性筛法只能求出这个数的素数因数个数和因数个数)。
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<algorithm> using namespace std; #define maxn 1000000 int vis[maxn+10],prime[maxn+10],tot,dp[maxn+10][10],cnt[maxn+10]; void init() { int i,j;cnt[1]=0; for(i=2;i<=maxn;i++){ if(!vis[i]){ cnt[i]=1; for(j=2*i;j<=maxn;j+=i){ vis[j]=1; cnt[j]++; } } } for(i=1;i<=7;i++){ dp[1][i]=0; } for(i=2;i<=maxn;i++){ for(j=1;j<=7;j++){ dp[i][j]=dp[i-1][j]; } dp[i][cnt[i]]++; } } int main() { int n,m,i,j,T; int num1[10]; init(); scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(i=1;i<=7;i++){ num1[i]=dp[m][i]-dp[n-1][i]; } if(num1[7]>=2){ printf("7\n");continue; } if(num1[6]>=2){ printf("6\n");continue; } if(num1[5]>=2){ printf("5\n");continue; } if(num1[4]>=2){ printf("4\n");continue; } if(num1[3]>=2 || (num1[6]==1 && num1[3]==1)){ printf("3\n");continue; } if(num1[2]>=2 || (num1[6]==1 && num1[4]==1) || (num1[6]==1 && num1[2]==1) || (num1[4]==1 && num1[2]==1)){ printf("2\n");continue; } printf("1\n"); } return 0; }