题目地址:HDU 5371
题意:每次T(1000000)次询问,每次询问有一个区间[L, R] (2 <= L < R <= 1000000 )。 f(i) 表示的是数i的素因子种类数。 然后求这个区间内GCD(f(i), f(j))的最大值,(L <= i < j <= R )。
思路:2*3*5*7*9*11*13=270270<1e6<2*3*5*7*9*11*13*17=4594590.所以f的最大值为7。开一个cnt[ maxn ] [ 8 ] 的数组来记录在第 i 个数之前(1-7)数字各出现了几次。 然后每次只要暴力这7个数来确定最大的gcd就行了。最后遍历的时候记得分情况讨论一下。
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <set>
#include <queue>
#include <stack>
#include <map>
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
const int inf=0x3f3f3f3f;
const double pi= acos(-1.0);
const double esp=1e-6;
const int maxn=1e6+10;
int isprime[maxn];
int f[maxn];
int cnt[maxn][8];
int tmp[8];
void Solve()
{
memset(isprime,0,sizeof(isprime));
for(int i=2;i<=maxn;i++){
if(!isprime[i]){
f[i]=1;
for(int j=i*2;j<=maxn;j+=i){
isprime[j]=1;
f[j]+=1;
}
}
}
for(int i=2;i<=maxn;i++){
for(int j=1;j<=7;j++){
cnt[i][j]=cnt[i-1][j];
}
cnt[i][f[i]]++;
}
}
int gcd(int a,int b)
{
while(b!=0){
int r=b;
b=a%b;
a=r;
}
return a;
}
int main()
{
int T,l,r;
int maxx;
scanf("%d",&T);
Solve();
while(T--){
memset(tmp,0,sizeof(tmp));
scanf("%d %d",&l,&r);
for(int i=1;i<=7;i++)
tmp[i]=cnt[r][i]-cnt[l-1][i];
maxx=-inf;
for(int i=1;i<=7;i++)
for(int j=1;j<=7;j++){
if(i==j&&tmp[i]>=2)
maxx=max(maxx,i);
else if(i!=j&&tmp[i]>=1&&tmp[j]>=1)
maxx=max(maxx,gcd(i,j));
}
printf("%d\n",maxx);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u013486414/article/details/47129603