这题大意是要你求a!/b!这个结果可以被拆分成多少个素因子的乘积。很明显我们必须求出每一个数能够拆分成多少个素因子,因为相邻两个数或者几个数是没有关系的。数据非常大,t都有100万,所以我们必须吧1-5000000的书都预处理之后在进行输出。最开始想到了这个想法但是做法超时了,就不提自己的做法了,讲讲看了别人的做法思路:
还是对每一个数字求解能分成多少个素因子,也是对素数进行while循环的除,但是并不是在素数里面一个一个找,而是直接对素数进行除,这个想法和素数筛选法是差不多的。也就是说我们由一个素数开始,直接对他的2,倍,3倍,4倍.......n倍进行处理,这样就是O(n)的时间复杂度,比如说2,就对4,6,8,10....直接处理,省去了查找的时间。然后利用前缀和,将前面都有的加起来再加上自己的就是一直到这里的个数,最后做减法就OK。
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
int a[5000002];
int dp[5000005];
void Prime2()
{
memset(a,0,sizeof(a));
memset(dp,0,sizeof(dp));
dp[1]=0;
long long i,j,k;
for(i=2;i<=5000000;i++)
{
if(!a[i])
{
for(j=i;j<=5000000;j+=i)
{
k=j;
while(k%i==0)
{
k/=i;
dp[j]++;
}
a[j]=1;
}
}
}
for(i=2;i<=5000000;i++)
{
dp[i]=dp[i]+dp[i-1];
}
}
int main()
{
int a1,b1;
int t;
scanf("%d",&t);
Prime2();
while(t--)
{
scanf("%d%d",&a1,&b1);
printf("%d\n",dp[a1]-dp[b1]);
}
return 0;
}
需要注意的点:
(1)如果你的答案这里用的是for(j=i*;j<=5000000;j+=i)那么就需要在处理一下,比如42,除以2,除以3之后还有7,但是到7的时候49>42了,那么他也就跑不动了,这个7也就掉了。所以需要注意,再者,i可以到500万明显i*i超出了int的范围。
(2)t的数量有100万,那么卡输入输出函数非常紧,用cin,cout必死无疑。