Codeforces Round #713 (Div. 3) G. Short Task(数论-因素)

题意很明确,我们所要处理的就是求出,每个数的因素之和即可,范围限定在1e7内,那么在这里由初等数论求因素的和,我们就知道要先去求每个数的最小质因数。

数论:
假设x=p1a1+p2a2+p3a3
一个正整数的因素个数为(a1+1)(a2+2)(a3+3)
一个正整数的所有因素之和为(1+p11+p12+**+p1a1)(1+p21+p22+**+p2a2)(1+p31+p32+***+p3a3)

在这个结论的前提下,我们可以在接近线性时间的复杂度下筛出每个数的最小质因数,然后进行因素和的求解,进行预处理,最后解决问题。
代码如下:

/*
 * @Author: c's'c
 * @Date: 2021-04-12 13:44:56
 * @LastEditTime: 2021-04-12 15:01:50
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \code_formal\cf\CF_713_7.CPP
 */
#include <bits/stdc++.h>
#define pr printf
#define sc scanf
#define sf(n) scanf("%d", &n)
#define sff(n1, n2) scanf("%d %d", &n1, &n2)
#define sfff(n1, n2, n3) scanf("%d %d %d", &n1, &n2, &n3)
#define sl(n) scanf("%lld", &n)
#define sll(n1, n2) scanf("%lld %lld", &n1, &n2)
#define slll(n1, n2, n3) scanf("%lld %lld %lld", &n1, &n2, &n3)
#define for0(i, n) for (i = 0; i < n; i++)
#define for1n(i, n) for (i = 1; i <= n; i++)
#define foran(i, a, n) for (i = a; i <= n; i++)
#define forna(i, a, n) for (i = n; i >= a; i--)
#define pb push_back
#define fi first
#define se second
#define int long long
#define endl '\n'
#define vi vector<int>
#define vii vector<vector<int>>
#define mem(ara, n) memset(ara, n, sizeof(ara))
#define memb(ara) memset(ara, false, sizeof(ara))
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))
#define sz(x) x.size()
const int N = 10000100;
const int mod = 1e9 + 7;
namespace fastIO
{
    inline void input(int &res)
    {
        char c = getchar();
        res = 0;
        int f = 1;
        while (!isdigit(c))
        {
            f ^= c == '-';
            c = getchar();
        }
        while (isdigit(c))
        {
            res = (res << 3) + (res << 1) + (c ^ 48);
            c = getchar();
        }
        res = f ? res : -res;
    }
    inline int qpow(int a, int b)
    {
        int ans = 1, base = a;
        while (b)
        {
            if (b & 1)
                ans = (ans * base % mod + mod) % mod;
            base = (base * base % mod + mod) % mod;
            b >>= 1;
        }
        return ans;
    }
    int fact(int n)
    {
        int res = 1;
        for (int i = 1; i <= n; i++)
        {
            res = res * 1ll * i % mod;
        }
        return res;
    }
    int C(int n, int k)
    {
        return fact(n) * 1ll * qpow(fact(k), mod - 2) % mod * 1ll * qpow(fact(n - k), mod - 2) % mod;
    }
}
using namespace fastIO;
 
using namespace std;
 
int n, m;
int s[N], d[N], ans[N];
vi primes;
 
signed main()
{
    fill(d, d + N, -1);
    d[1] = 1;
 
    int i;
    foran(i, 2, N)
    {
        if (d[i] == -1)
        {
            primes.emplace_back(i);
            d[i] = i;
        }
        for (auto &x : primes)
        {
            if (x > d[i] || x * i > N)
                break;
            d[x * i] = x;
        }
    }
 
    s[1] = 1;
    for (int i = 2; i < N; i++)
    {
        int j = i;
        s[i] = 1;
        while (j % d[i] == 0)
        {
            j /= d[i];
            s[i] = s[i] * d[i] + 1;
        }
        s[i] *= s[j];//互质
    }
 
    fill(ans, ans + N, -1);
 
    for (int i = N - 1; i > 0; i--)
        if (s[i] < N)
            ans[s[i]] = i;
 
    int _ = 1;
    input(_);
    while (_--)
    {
        cin >> n;
        cout << ans[n] << endl;
    }
 
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值