欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CodeForces - 546D Soldier and Number Game(质因数分解计数)

程序员文章站 2024-02-21 14:36:34
...

CodeForces - 546D Soldier and Number Game(质因数分解计数)

样例解释:

3!/1!=23=>ans=23!/ 1!=2*3=>ans=2
6!/3!=456=22235=>ans=56!/3!=4*5*6=2 * 2* 2*3*5=>ans=5

思路:

对1~5e6的每个数进行质因数计数,求前缀和,然后就可以O(1)输出ans了。
设pnum[i]是i的质因子的个数,i = a * b,则有pnum[i] = pnum[a] + pnum[b]。
举个例子:
36=49pnum[36]=pnum[4]+pnum[9]=22=436=4*9,则pnum[36]=pnum[4]+pnum[9]=2*2=4

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define ms(x,a) memset(x,a,sizeof(x))
using namespace std;
const int maxn = 5e6 + 10;
const ll mod = 1e9 + 7;
int n,m;

int cnt;
bool v[maxn];
ll p[maxn],sm[maxn];

void get_pnum(int x)
{
    int y = x;
    for(int i = 1; p[i] * p[i] <= x; i++)
    {
        while(x % p[i] == 0)
        {
            sm[y]++;
            x /= p[i];
            if(sm[x])
            {
                sm[y] += sm[x];
                return ;
            }
        }
    }
    if(x > 1)sm[y]++;
    return ;
}

void Prime()
{
    cnt = 0;
    ms(p,0);
    ms(v,0);
    ms(sm,0);
    v[1] = 1;
    for(int i = 2; i < maxn; i++)
    {
        if(!v[i])
        {
            p[++cnt] = i;
        }
        for(int j = 1; j <= cnt && p[j] * i <= maxn; j++)
        {
            v[i * p[j]] = 1;
            if(i % p[j] == 0)
                break;
        }
    }
    for(int i = 1; i < maxn; i++)
    {
        get_pnum(i);
    }
    for(int i = 1; i < maxn; i++)
    {
        sm[i] += sm[i - 1];
    }
}

void solve(){
    Prime();
    int t;
    scanf("%d",&t);
    for(int ca = 1; ca <= t; ca++)
    {
        scanf("%d%d",&n,&m);
        printf("%lld\n",sm[n] - sm[m]);
    }
    return ;
}

int main()
{
    solve();
    return 0;
}

//Dawn_Exile


相关标签: codeforces