一个数的约数和,约数个数问题

一个数的约数个数

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
#define speed(x) ios::sync_with_stdio(false), cin.tie(x), cout.tie(x)
#define bug(x) cout << #x << " == " << x << '\n'
const ll MAX_N =1e6+10;
int tot=0;
ll prime[MAX_N] = { 0 };///范围n里面的素数
bool isp[MAX_N] = {0};///是不是为素数
int d[MAX_N] = { 0 };///约数数量
int num[MAX_N] = { 0 };///最小素数因子个数数量

inline void init(int n)///线性筛求约数个数
{
    d[1] = 1;
    for(int i=2;i<=n;i++)
    {
        if(!isp[i])///是素数的话
        {
            d[i]=2;///约数数量
            num[i]=1;///他自己就是最小素数因子
            tot++;
            prime[tot]=i;
        }
        for(int j=1;j<=tot && prime[j]*i<=n;j++)///不加后面那个条件可能会越界 我已经体会到了QwQ
        {
            isp[prime[j]*i] = 1;
            if(i%prime[j]==0)///prime[j]是i的最小素因子
            {

                num[i*prime[j]]=num[i]+1;
                d[i*prime[j]]=d[i]/( num[i]+1 )*(num[ i*prime[j] ]+1);
                ///约数数量为(每一位素因子的个数+1)相乘
                ///e.g:interage=p1^a1*p2^a2......pn^an.d[interage]=(1+a1)*(1+a2)....(an+1)
                ///而i*prime[j]与i的区别只是增加了一个最小素因子
                ///因此d[i*prime[j]]=d[i]/( num[i]+1 )*( num[i]+1+1)
                break;
            }
            d[ i*prime[j] ]=d[i]*2;///最小素因子的值改变,而且a1=1,a1+1=2,所以×2就好
            num[ i*prime[j] ]=1;///i*prime[j]目前最小素因子为prime[j]
        }
    }
}

int main()
{
    ll n;
    scanf("%lld",&n);
    init(n);
    for(int i=1; i<=n; i++)
    {
        printf("%lld ",d[i]);
    }
}

一个数的约数和

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
#define speed(x) ios::sync_with_stdio(false), cin.tie(x), cout.tie(x)
#define bug(x) cout << #x << " == " << x << '\n'
const ll MAX_N =1e6+10;
int tot=0;
ll prime[MAX_N] = { 0 };///范围n里面的素数
bool isp[MAX_N] = {0};///是不是为素数
ll sd[MAX_N] = {0};///约数和
ll sp[MAX_N] = {0};///最小素因子等比数列的和1+p1^1+p1^2+...+p1^a1
inline void init(ll n)///线性筛求约数个数
{
    sd[1] = 1;
    for(ll i=2; i<=n; i++)
    {
        if(!isp[i])///是素数的话
        {
            sd[i]=i+1;
            sp[i]=1+i;
            tot++;
            prime[tot]=i;
        }
        for(int j=1; j<=tot&&prime[j]*i<=n; j++)
        {
            isp[prime[j]*i] = 1;
            if(i%prime[j]==0)///prime[j]是i的最小素因子
            {
                 sp[ i*prime[j] ] = sp[i]*prime[j]+1;
                sd[i*prime[j]] = (sd[i]/sp[i]) * sp[ i*prime[j] ];
                ///i*prime[j]的最小素因子的等比数列为1+p1^1+p1^2+...+p1^(a1+1)=p1(1+p1^1+...+p1^a1)+1
                break;
            }
            sd[ i*prime[j] ] = sd[i]*sd[ prime[j] ];
            sp[ i*prime[j] ] = sp[ prime[j] ];
        }
    }
}
int main()
{
    ll n;
    scanf("%lld",&n);
    init(n);
    for(int i=1; i<=n; i++)
    {
        printf("%lld\n",sd[i]);
        ///o[i] = o[i-1] + sd[i];
        ///printf("%lld ",(ll)i*n-o[i]);
    }
}

1~x中 每一个数的约数和 的和(利用除法分块写)

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
#define speed(x) ios::sync_with_stdio(false), cin.tie(x), cout.tie(x)
#define bug(x) cout << #x << " == " << x << '\n'
const ll MAX_N =1e6+10;

ll solve(ll n)
{
    ll ans=0;
    ll r=1;
    for(ll l=1;l<=n;l=r+1)
    {
        r=n/(n/l);
        ans += (n/l) * (l+r)*(r-l+1)/2;
    }
    return ans;
}
int main()
{
    ll x;
    scanf("%lld %lld",&x);
  
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值