题意:
两个人每轮取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; }