题意:
两个人每轮取n的一个因子k,将n/k交给另一个人,n初始值为a!/b!,n为1时结束。求可以进行多少轮。
思路:
可以利用合适的素数筛筛选出MAXN范围内的素数,同时可以计算每一个数可以分解的因子数。然后利用前缀和计算出来前a个数的因子数和,计算时用dp[a]-dp[b]即可。
代码:
#include<stdio.h>
#include<string.h>
#include<string>
#include<iostream>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
const int MAXN = 5e6;
int n,m,a[MAXN+5];
int num[MAXN+5],cnt[MAXN+5],dp[MAXN+5];
bool is_prime[MAXN+5];
void shai()
{
memset(is_prime,1,sizeof is_prime);
memset(cnt,0,sizeof cnt);
for(int i=1;i<=MAXN;i++)
num[i]=i;
for(int i=2;i<=MAXN;i++)
{
if(is_prime[i])
{
cnt[i]++;
for(int j=i+i;j<=MAXN;j+=i)
{
while(num[j]%i==0)
{
num[j]/=i;
cnt[j]++;
}
is_prime[j]=0;
}
}
}
}
int main()
{
memset(dp,0,sizeof dp);
shai();
for(int i=1;i<=MAXN;i++)
dp[i]=dp[i-1]+cnt[i];
int t;
scanf("%d",&t);
while(t--)
{
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",dp[a]-dp[b]);
}
return 0;
}