2021牛客寒假算法基础集训营2 I 牛牛的“质因数”(数学)
牛牛的“质因数”
https://ac.nowcoder.com/acm/contest/9982/I
Description
牛牛定义了一个函数F(x),它表示将x做质因数分解后得到的数字从小到大升序排列,然后将其“拼接”成一个大整数。
例如1500=22355*5,F(1500)=223555。
牛牛现在想要知道 的值。
Solution
, 考虑朴素做法:筛出
的素数,对于
的每一个数字进行质因数分解
模拟, 预处理长度后
拼接上去。我的模拟做法大概是时间复杂度大概是
。
考虑优化:在埃氏筛中,筛法每次遍历素数的所有倍数,显然每次可以 实现上述
的递推。具体做法是,如果对于素数
, 如果
,那么显然有
——相当于在后面先填上
个0,这个过程可以做
次。
举个例子,,那么在埃氏筛的时候,
最后统计答案的时候计算 即可
时间复杂度约为 ——具体我也不知道怎么算
Code
#include <bits/stdc++.h>
#pragma GCC optimize(3)
typedef long long ll;
using namespace std;
const int N = 4e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
ll dp[N];
bool vis[N];
int prime[N], tot;
void solve() {
std::function<void(int)> init = [&](int n) -> void {
for(int i = 2; i <= n; i++) {
if(!vis[i]) {
prime[++tot] = i;
dp[i] = i; // 素数的贡献为本身
int pre = i;
int len = 0, need = 1; // 长度
while(pre) {
pre /= 10; len++, need *= 10;
}
for(int j = 2 * i; j <= n; j += i) {
vis[j] = 1;
int cur = j;
while(cur % i == 0) {
cur /= i;
dp[j] = (dp[j] * need % mod + i) % mod;
}
}
}
}
};
int n; cin >> n;
init(n);
ll ans = 0;
for(int i = 2; i <= n; i++) {
ans += dp[i];
ans %= mod;
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
int T = 1; //cin >> T;
while(T--) {
solve();
}
return 0;
} Kurisu与牛客的每日一题 文章被收录于专栏
每日一题

查看17道真题和解析