【篩法,思維,數學】牛客比賽NC210203I 牛牛的質因數
阿新 • • 發佈:2021-02-15
技術標籤:數論
連結:https://ac.nowcoder.com/acm/contest/9982/I
來源:牛客網
一、題目簡介
牛牛最近對於質因數分解產生了濃厚的興趣。
牛牛定義了一個函式F(x),它表示將x做質因數分解後得到的數字從小到大升序排列,然後將其“拼接”成一個大整數。
例如1500=22355*5,F(1500)=223555。
牛牛現在想要知道∑ F(i)的值。
由於這個結果非常大,所以你只用告訴牛牛最終答案對10^9+7取餘數的結果即可。
輸入描述:
僅一行一個正整數n(2≤n≤4×10^6)
輸出描述:
僅一行,表示答案對10^9+7取餘數的結果。
示例1
輸入
3
輸出
5
示例2
輸入
10
輸出
342
說明
F(2)=2
F(3)=3
F(4)=22
F(5)=5
F(6)=23
F(7)=7
F(8)=222
F(9)=33
F(10)=25
2+3+22+5+23+7+222+33+25=342
二、題目分析
埃氏篩思想,利用f[i]計算f[i * m],即倍數的遞推。普通的pow()函式可能不夠用,可以自己寫一個快速冪。特別注意前i中最大質數的位數,一位就* 10,兩位就*100,以此類推。
程式碼
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
ll f[4000010],mod=1e9+7;
int n;
ll power(ll a,ll b){return b?power(a*a%mod,b/2)*(b%2?a:1)%mod:1;} //自定義pow,快速冪思想
int main()
{
cin>>n;
for(int i=2;i<=n;i++){ //採用埃氏篩的思想去篩f[]
if(f[i]==0) {
f[i]=i; //如果是質數就等於自身
for(int j=i+i; j<=n;j+=i) //篩掉i的倍數
f[j]=((f[j/i]*(ll)power(10,(ll)(log10(i)+1)))%mod+i)%mod;
}
}
ll ans=0;
for(int i=2;i<=n;i++) ans=(ans+f[i])%mod;
cout<<ans<<endl;
return 0;
}