标签:pre return 不同 sum acm blank prime else init
题目链接:HDU 5317 RGCDQ
题意:定义函数F(x)为x的不同的素因子且小于等于x的个数。询问[l,r]区间中gcd(F(i),F(j))的最大值。
思路:暴力预处理出全部的合数分解结果。发现F(x)最大也仅仅有7。之后就是暴力求出全部1到7出现次数的前缀和。询问的时候就打到O(1)了。
AC代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define MAXN 1000010
bool isPrime[MAXN+10];
int Prime[800000+10];
int sum[8][MAXN+10];
int d[MAXN+10];
int cnt=0;
void init(){
int i,j;
memset(isPrime,true,sizeof isPrime);
isPrime[0]=isPrime[1]=false;
for(i=2;i<=MAXN;i++){
if(!isPrime[i]) continue;
Prime[cnt++]=i;
for(j=i+i;j<=MAXN;j+=i)
isPrime[j]=false;
}
}
int slove(int x){
int i,ans;
ans=0;
for(i=0;Prime[i]*Prime[i]<=x && i<cnt;i++){
if(x%Prime[i]==0){
while(x%Prime[i]==0){
x/=Prime[i];
}
ans++;
}
}
if(x!=1) ans++;
return ans;
}
void Pre(){
init();
int i,j;
memset(sum,0,sizeof sum);
memset(d,0,sizeof d);
for(i=2;i<=MAXN;i++) {
d[i]=slove(i);//f函数的值
}
for(i=1;i<=7;i++){
for(j=1;j<=MAXN;j++){
if(d[j]==i)
sum[i][j]=sum[i][j-1]+1;
else sum[i][j]=sum[i][j-1];
//printf("%d:%d..",j,sum[i][j]);
//getchar();
}
}
}
int gcd(int x,int y){
if(y==0) return x;
return gcd(y,x%y);
}
int main(){
Pre();
int t,l,r,i,j;
scanf("%d",&t);
while(t--){
scanf("%d %d",&l,&r);
int ans=1;
for(i=1;i<=7;i++){
for(j=1;j<=7;j++){
int a=sum[i][r]-sum[i][l-1];
int b=sum[j][r]-sum[j][l-1];
if(a==0 || b==0)//表示个数是0说明个数为i或j没有出现
continue;
if(i!=j || a>=2){
ans=max(ans,gcd(i,j));
}
}
}
printf("%d\n",ans);
}
return 0;
}
/*
4 9
1
100 1000
4
213 454
4
112 1111
4
5 1111
4
1111 11111
5
11111 111111
6
111111 999999
6
999991 1000000
3
*/标签:pre return 不同 sum acm blank prime else init
原文地址:http://www.cnblogs.com/jzdwajue/p/6956486.html