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

在这里插入图片描述

样例解释:

3 ! / 1 ! = 2 ∗ 3 = > a n s = 2 3!/ 1!=2*3=>ans=2 3!/1!=23=>ans=2
6 ! / 3 ! = 4 ∗ 5 ∗ 6 = 2 ∗ 2 ∗ 2 ∗ 3 ∗ 5 = > a n s = 5 6!/3!=4*5*6=2 * 2* 2*3*5=>ans=5 6!/3!=456=22235=>ans=5

思路:

对1~5e6的每个数进行质因数计数,求前缀和,然后就可以O(1)输出ans了。
设pnum[i]是i的质因子的个数,i = a * b,则有pnum[i] = pnum[a] + pnum[b]。
举个例子:
36 = 4 ∗ 9 , 则 p n u m [ 36 ] = p n u m [ 4 ] + p n u m [ 9 ] = 2 ∗ 2 = 4 36=4*9,则pnum[36]=pnum[4]+pnum[9]=2*2=4 36=49pnum[36]=pnum[4]+pnum[9]=22=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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值