CH3101 质数分解的灵活处理

CH3101 质数分解的灵活处理

CH3101 题面

思路
直接对N!分解肯定不行的,想到N!的最大因子就是N,并且N!的所有因子就是1-N中所有数的因子之和,对1-N中每一个数进行质因数分解肯定也是不现实的,因此转移变量,对于每一个数考虑因子太慢,不如考虑每个因子对于所有数的个数,对于因子p,[1,N]中至少只有一个p因子的数有[N/p]个
,对于含有p^2的因子的数有[N/p]个,本来两个因子应该被计两次数,但是至少一个因子时计过了这部分数,因此不用乘2,我们易得对于一个因子p,N!中的个数为:
在这里插入图片描述
这里所有的[]表示高斯函数,显然可以看出只需要O(logn)的时间,因此总体加上筛质数的时间总共是O(nloglogn+nlogn)(这里也可以直接筛到1e6)

注意事项
1)这里对prime存储之后一定要上限设置,即i<prime.size(),不能只用prime[i]<=n,否则会接着向后走发生除0错误
2)这里原书作者用了一个写法for (int j = n; j; j /= p) c += j / p来对p的个数进行计算,代替了每一次乘p+判断,妙!注意:p,p^2 ……, p^m, n,序列与n/q,n/q^2, ……,n/q^m 生成的序列是一样的,只不过倒序,或者说,把n等价于q^m次方,这样算等价于 q^ m/q^ i

复习反省
绝了,声明数组忘了大小忘了+1,正好num是在used后面声明的,然后改used的时候改到maxn下标时,数组越界但不报错,剩下的这个地址就是num的(变量赋地址的连续性),正好把num改了……质数表就错了

代码

#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e6;
int used[maxn+1];
typedef long long ll;
vector<ll> prime;

ll num = 0;
void eratothenes()
{
    memset(used,0,sizeof(used));
    for(int i = 2;i*i <=maxn;i++)
    {
        if(!used[i])
        {
            for(int j = 2;j*i<=maxn;j++)
            {
                used[j*i] = 1;
            }
        }
    }
    for(int i = 2;i<=maxn;i++)
        if(!used[i]) prime.push_back(i);
}

int main()
{
    eratothenes();
    ll tmp,note,sum;
    ll n;
    cin >> n;
    if(n== 1) cout << 1 <<' '<<1<<endl;
    else
    {
        for(int i = 0;i<prime.size()&&prime[i] <=n;i++)
    {
        note = prime[i];
        tmp = note;
        sum = 0;
        for(int j = 1;tmp<=n;j++)
        {
            sum+=n/tmp;
            tmp *=note;
        }
        cout << note <<' '<< sum<<endl;
    }
    }
    
   
    system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值