题意:给定区间[a,b](a,b<10^6),f(x)表示x包含不同素因子的个数,求[a,b]中的maxgcd(f(i),f(j))(a<=i,j<=b);
思路:对于10^6,每个数不超过7个素因子。
预处理出10^6中从1开始的每段区间中f(x)每种情况的数量和。
如果区间中某种f(x)的情况的个数不少于2,则该情况成立,取最大的情况;
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int s[1000100][8]; int t,n,m,num; int vis[1000100],su[1000100]; void biao() { int i,j,k; num=0; memset(vis,0,sizeof(vis)); vis[0]=vis[1]=1; for(i=2;i<=1000100;i++){ if(!vis[i]) su[num++]=i; if(!vis[i]) for(j=i*2;j<=1000100;j+=i){ vis[j]=1; } } } int cal(int x) { int ret = 0; for(int j=0; su[j]*su[j]<=x; j++) { if(x%su[j]==0) { ret++; while(x%su[j]==0){ x/=su[j]; } if(!vis[x]){ ret++; break; } } } return ret; } void pre() { int cnt,temp; memset(s,0,sizeof(s)); s[2][1]=1; for(int i=1;i<=1000100;i++){ s[i][1]=s[i-1][1];s[i][2]=s[i-1][2]; s[i][3]=s[i-1][3];s[i][4]=s[i-1][4]; s[i][5]=s[i-1][5];s[i][6]=s[i-1][6]; s[i][7]=s[i-1][7]; cnt=cal(i); if(!vis[i]) cnt=1; s[i][cnt]++; } } int main() { int i,j,k,a,b; biao(); pre(); //printf("%d\n",vis[143]); //printf("%d\n",cal(2310)); //printf("%d\n",num); while(scanf("%d",&n)!=EOF) { for(i=0;i<n;i++){ scanf("%d%d",&a,&b);a--; if(s[b][7]-s[a][7]>=2){ // printf("%d %d\n",s[b][7],s[a][7]); printf("7\n");continue; } else if(s[b][6]-s[a][6]>=2){ printf("6\n");continue; } else if(s[b][5]-s[a][5]>=2){ printf("5\n");continue; } else if(s[b][4]-s[a][4]>=2){ printf("4\n");continue; } else if(s[b][3]-s[a][3]>=2){ printf("3\n");continue; } else if(s[b][2]-s[a][2]>=2){ printf("2\n");continue; } else printf("1\n"); } } return 0; }
时间: 2024-12-16 23:08:17