一个数的约数个数
#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);
}