比赛的时候被卡疯了……大部分时间都在耗这题 两小时左右的一发TLE 结束后拿那代码一交 A了!。。。坑 不过还是思路不正 当时用的线段树 通过这题也学了个给力技能 前缀数组 求的时候直接取差即可
代码如下:
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int p[111111],tp,num[1000005],qz[1000005][8],cs[8];
bool IsPrim[1000001];
void Get()
{
memset(IsPrim,0,sizeof(IsPrim));
tp = 0;
int i,j;
for(i = 2; i <= 1000000; ++i)
{
if(!IsPrim[i]) p[tp++] = i;
for(j = 0; j < tp && p[j]*i <= 1000000; ++j)
{
IsPrim[p[j]*i] = true;
if(!(i%p[j])) break;
}
}
}
int Getg(int x)
{
int i;
i = 0;
if(!IsPrim[x]) return 1;
while(x%p[i] && i < tp)
{
i++;
}
if(x%p[i]) return 1;
return !((x/p[i])%p[i])? num[x/p[i]]: num[x/p[i]]+1;
}
int main()
{
//freopen("in.in","r",stdin);
//reopen("out.out","w",stdout);
int i,j,l,r,t,ans;
num[1] = 0;
Get();
for(i = 2; i <= 1000000; ++i)
{
num[i] = Getg(i);
}
memset(qz,0,sizeof(qz));
for(i = 2; i <= 1000000; ++i)
{
for(j = 1; j <= 7; ++j) qz[i][j] = qz[i-1][j];
qz[i][num[i]]++;
}
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&l,&r);
for(i = 1; i <= 7; ++i) cs[i] = qz[r][i] - qz[l-1][i];
ans = -1;
for(i = 1; i <= 7; ++i)
{
if(!cs[i]) continue;
for(j = i; j <= 7; ++j)
{
if(cs[j] && (j != i || (j == i && cs[j] >= 2) ))
ans = max(ans,__gcd(i,j));
}
}
printf("%d\n",ans);
}
return 0;
}