1. 程式人生 > 其它 >【篩法,思維,數學】牛客比賽NC210203I 牛牛的質因數

【篩法,思維,數學】牛客比賽NC210203I 牛牛的質因數

技術標籤:數論

連結: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; }