Codeforces Round #304 (Div. 2)(CF546D) Soldier and Number Game(线性筛)

发布时间:2020-10-03 发布网站:编程之家
编程之家收集整理的这篇文章主要介绍了Codeforces Round #304 (Div. 2)(CF546D) Soldier and Number Game(线性筛)编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

题意

给你a,b(1<=b<=a<=5000000)表示a!/b!表示的数,你每次可以对这个数除以x(x>1且x为这个数的因子)使他变成a!/b!/x,问你最多可以操作多少次使这个数变成1

http://codeforces.com/problemset/problem/546/D

思路

显然要素因子分解,但直接计算a!/b!的素因子个数太慢了,可以发现实际上是计算a(a-1)(a-2)……(b+1),而这些数之积的所有素因子个数之和是等于每个数的素因子个数之和的(相当于对每一个数除以x的操作次数之和),所以我们线性筛的时候计算一下素因子个数即可,最后用前缀和搞一搞O(1)输出。

代码

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int N=5e6+5;
const int mod=1e9+7;
const double eps=1e-8;
const double PI = acos(-1.0);
#define lowbit(x) (x&(-x))
ll sum[N];
int vis[N],prime[N],tot;
void shai()
{
    tot=0;
    memset(vis,sizeof(vis));
    for(int i=2;i<N;i++)
    {
        if(!vis[i])
            prime[tot++]=i,sum[i]=1;
        for(int j=0;j<tot&&prime[j]*i<N;j++)
        {
            vis[prime[j]*i]=1;
            sum[prime[j]*i]=sum[i]+1;
            if(i%prime[j]==0)
                break;
        }
    }
    for(int i=2;i<N;i++)
        sum[i]+=sum[i-1];
}
int main()
{
    std::ios::sync_with_stdio(false);
    int n;
    shai();
    scanf("%d",&n);
    while(n--)
    {
        ll a,b;
        scanf("%d%d",&a,&b);
        printf("%lld\n",sum[a]-sum[b]);
    }
    return 0;
}

总结

以上是编程之家为你收集整理的Codeforces Round #304 (Div. 2)(CF546D) Soldier and Number Game(线性筛)全部内容,希望文章能够帮你解决Codeforces Round #304 (Div. 2)(CF546D) Soldier and Number Game(线性筛)所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您喜欢交流学习经验,点击链接加入编程之家官方QQ群:1065694478