标签:
题目连接:戳ME
题意:在一个[L,R]内找到最大的gcd(f[i],f[j])其中L<=i<j<=R,f[x]表示i分解质因数后因子的种类数。eg:f[10]=2(10=2*5),f[12]=2(12=2*2*3)。
分析:很容易想到先将f[x]求出来,这里x最大1e6,要在常数时间内求出f[x]。并且稍加分析就知道1<=f[x]<=7,可以用一个dp[i][j]表示从f[1]到f[i]有多少个j。这样就可以在常数时间内预处理出来,后面在O(1)的时间内就可以输出结果。并且这个题并不用把GCD求出来,区间里最大的f[x]就是这个区间出现次数>=2次的最大的f[x]。具体看代码。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define clc(a, b) memset(a, b, sizeof(a)) 5 using namespace std; 6 const int M = 1e6+5; 7 int dp[M][8]; 8 int f[M]; 9 10 void Pre() // 预处理函数, 11 { 12 memset( dp, 0, sizeof(dp) ); 13 memset( f, 0, sizeof(f) ); 14 for( int i = 2; i < M; i++ ) // 首先将f(x)求出来,保存在f[]数组中 15 { 16 if( f[i] ) 17 continue; 18 f[i] = 1; 19 for( int j=2; j*i<M; j++ ) 20 { 21 f[j*i]++; 22 } 23 } 24 dp[2][1] = 1; 25 for(int i=3; i<M; i++) // 预处理dp[]数组 26 { 27 for(int j=1; j <= 7; j++) 28 { 29 dp[i][j] = dp[i-1][j]; 30 } 31 dp[i][f[i]]++; 32 } 33 } 34 35 int main() 36 { 37 Pre(); 38 int t; 39 scanf("%d", &t); 40 while( t-- ) 41 { 42 int a, b; 43 scanf("%d %d", &a, &b); 44 int ret = 0; 45 for( int i=1; i<8; i++ ) 46 { //保证i出现2次 //保证i出现过 47 if( dp[b][i]-dp[a-1][i] > 1 && dp[b][i] ) 48 ret = max( ret, i ); 49 } 50 printf("%d\n", ret); 51 } 52 }
HDU OJ 5317 RGCDQ( 2015多校联合训练第3场) 暴力+小技巧
标签:
原文地址:http://www.cnblogs.com/TaoTaoCome/p/4685395.html