题目链接:点击打开链接
题目大意:定义f(i)为组成i的素数的种类,求在区间[l,r]内的gcd(f(i),f(j)) (l <= i < j <= r)的最大值
素数筛筛出10^6内的素数,求出每一个数的f(i),可以发现f(i) <= 7,用一个数组统计一下s[i][j]从2到i内f(x)=j有多少个,在计算区间的时候直接相减,判断一下最大的gcd
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std ; #define LL __int64 #define maxn 1000000+10 int a[maxn] , check[maxn] ; int tot ; int num[maxn] ; int s[maxn][10] ; void get_pri() { int i , j ; tot = 0 ; memset(check,0,sizeof(check)) ; for(i = 2 ; i <= 1000000 ; i++) { if( !check[i] ) a[tot++] = i ; for(j = 0 ; j < tot ; j++) { if( i*a[j] >= 1000000 ) break ; check[ i*a[j] ] = 1 ; if( i%a[j] == 0 ) break ; } } } int f(int x) { int j , cnt = 0 ; for(j = 0 ; a[j]*a[j] <= x ; j++) { if( x%a[j] == 0 ) cnt++ ; while( x%a[j] == 0 ) x /= a[j] ; if( x == 1 ) break ; } if( x != 1 ) cnt++ ; return cnt ; } int main() { int t , l , r ; int i , j , ans ; get_pri() ; for(i = 2 ; i <= 1000000 ; i++) num[i] = f(i) ; memset(s,0,sizeof(s)) ; for(i = 2; i <= 1000000 ; i++) { for(j = 1 ; j <= 7 ; j++) s[i][j] = s[i-1][j] ; s[i][ num[i] ]++ ; } scanf("%d", &t) ; while( t-- ) { scanf("%d %d", &l, &r) ; ans = 1 ; for(i = 1 ; i <= 7 ; i++) { s[0][i] = s[r][i]-s[l-1][i] ; if( s[0][i] > 1 ) ans = i ; } if( s[0][3]+s[0][6] == 2 ) ans = max(ans,3) ; if( s[0][2]+s[0][4]+s[0][6] >= 2 ) ans = max(ans,2) ; printf("%d\n", ans) ; } return 0 ; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-08 23:26:59