2021牛客寒假算法基础集训营2 I-牛牛的“质因数”

题目链接:点这里~

题目大意

  • F(x)表示将x做质因数分解后得到的数字从小到大升序排列,然后将其“拼接”成一个大整数。例如F(12)=223
  • \sum_{i=2}^{n}F(i)%(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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43911947/article/details/113621067