Codeforces546 D.Soldier and Number Game(线性筛)

    科技2022-07-21  102

    题意:

    给定a,b,表示有一个数为 a ! b ! \frac {a!}{b!} b!a!, 一次操作你可以选择一个它的因子x,然后将它除以x, 问最多能进行多少次操作。

    数据范围:b<=a<=5e6

    解法:

    设 f ( i ) 为 i 的 质 因 子 个 数 , g ( i ) = ∑ i = 1 n f ( i ) 设f(i)为i的质因子个数,g(i)=\sum_{i=1}^nf(i) f(i)ig(i)=i=1nf(i)

    那 么 答 案 为 g ( a ) − g ( b ) 那么答案为g(a)-g(b) g(a)g(b)

    线 性 筛 筛 出 f , 求 前 缀 和 求 出 g , 对 询 问 O ( 1 ) 输 出 即 可 . 线性筛筛出f,求前缀和 求出g,对询问O(1)输出即可. 线f,g,O(1).

    f 的 递 推 方 式 : f [ p r i m e [ j ] ∗ i ] = f [ i ] + 1 , ( p r i m e [ j ] 是 p r i m e [ j ] ∗ i 的 最 小 质 因 子 ) f的递推方式:f[prime[j]*i]=f[i]+1,(prime[j]是prime[j]*i的最小质因子) ff[prime[j]i]=f[i]+1(prime[j]prime[j]i)

    code:

    #include<bits/stdc++.h> using namespace std; #define ll long long #define PI pair<int,int> const int maxm=5e6+5; int np[maxm]; int p[maxm],c; ll f[maxm]; int n; void init(){ for(int i=2;i<maxm;i++){ if(!np[i]){ p[c++]=i; f[i]=1; } for(int j=0;j<c;j++){ if(1ll*p[j]*i>=maxm)break; np[p[j]*i]=1; f[p[j]*i]=f[i]+1; if(i%p[j]==0)break; } } for(int i=1;i<maxm;i++){ f[i]+=f[i-1]; } } signed main(){ init(); int T;scanf("%d",&T); while(T--){ int a,b;scanf("%d%d",&a,&b); printf("%lld\n",f[a]-f[b]); } return 0; }
    Processed: 0.010, SQL: 8