题目来源: CodeForces
基准时间限制:6 秒 空间限制:131072 KB 分值
两个士兵正在玩一个游戏,游戏开始的时候,第一个士兵为第二个士兵选一个正整数n。然后第二个士兵要玩尽可能多的轮数。每一轮要选择一个正整数x>1,且n要是x的倍数,然后用n/x去代替n。当n变成1的时候,游戏就结束了,第二个士兵所得的分数就是他玩游戏的轮数。
为了使游戏更加有趣,第一个士兵用 a! / b! 来表示n。k!表示把所有1到k的数字乘起来。
那么第二个士兵所能得到的最大分数是多少呢?
Input
单组测试数据。 第一行包含一个整数t (1 ≤ t ≤ 1,000,000),表示士兵玩游戏的次数。 接下来t行,每行包含两个整数a,b (1 ≤ b ≤ a ≤ 5,000,000)。
Output
对于每一组数据,输出第二个士兵能拿到的最多分数。
Input示例
2 3 1 6 3
Output示例
2 5
思路:筛法;求每个数的质因数的个数,因为上面的肯定整除下面的,所以只要质因数相减。
1 #include <stdio.h> 2 bool prime[5000005]; 3 int ans[5000005]; 4 int sum[5000005]; 5 int pre[5000005]; 6 int main(void) 7 { 8 int cn = 0;int i,j; 9 for(i = 2; i <= 5000000; i++) 10 { 11 if(!prime[i]) 12 { 13 pre[i] = i; 14 for(j = 2; (i*j) <= 5000000; j++) 15 { 16 prime[i*j] = true; 17 pre[i*j] = i; 18 } 19 } 20 } 21 ans[1] = 0; 22 ans[2] = 1; 23 for(i = 3; i <= 5000000; i++) 24 { 25 ans[i] = ans[i/pre[i]]+1; 26 } 27 ans[1] = 0; 28 sum[1] = 0; 29 for(i = 2; i <= 5000000; i++) 30 { 31 sum[i] = sum[i-1]+ans[i]; 32 } 33 int T; 34 scanf("%d",&T); 35 while(T--) 36 { 37 int x,y; 38 scanf("%d %d",&x,&y); 39 printf("%d ",sum[x]-sum[y]); 40 } 41 return 0; 42 }