题目链接:点这里~
题目大意
- F(x)表示将x做质因数分解后得到的数字从小到大升序排列,然后将其“拼接”成一个大整数。例如F(12)=223
- 求
%(1e9+7)
- 1<=n<=4e6
思路
- 训练赛有打表的,有dfs的,我这里是bfs广搜,深度最大是7,不会超时
- 用线性筛筛出n内所有质因子,然后是字符串拼接,取模求和
ac代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define debug(x) cout<<#x<<"="<<x<<endl
const int maxn = 4e6 + 5;
const int mod = 1e9 + 7;
ll prime[maxn],v[maxn], cnt;
string a[maxn];
void get_prime(int N){ //线性筛
for(int i=2;i<=N;i++){
if(!v[i]){
v[i]=i;prime[++cnt]=i;
}
for(int j=1;j<=cnt&&i*prime[j]<=N;j++){
if(prime[j]>v[i])break;
v[i*prime[j]]=prime[j];
}
}
}
ll cal(ll a, string b){ //整数与字符串求和取模
ll t = 0;
for(int i = 0; i < b.length(); i ++){
t = t * 10 + b[i] - '0';
t = t % mod;
}
return (a + t) % mod;
}
struct node{
string a; //字符串表示的大数
ll id, sum; //id表示从第几个质数开始拼接,sum是前几个质因子的乘积
};
int main(){
int n; scanf("%d", &n);
get_prime(n);
queue<node> q;
ll ans = 0;
for(int i = 1; i <= cnt; i ++){
a[i] = to_string(prime[i]);
q.push({a[i], i, prime[i]});
}
while(q.size()){
node t = q.front(); q.pop();
ans = cal(ans, t.a);
for(int i = t.id; i <= cnt; i ++){
string cc = t.a + a[i];
if(t.sum * prime[i] <= n) q.push({cc, i, t.sum * prime[i]});
else break; //及时退出
}
}
printf("%lld\n", ans);
return 0;
}