ACM模版

描述

题解

每次做到数论题我就头疼……实在是不知道怎么办了……给大家推荐一个不错的题解吧,数论实在是我的一个致命弱点。

>>>dance_in_the_dark<<< 的博客,大佬公式给的十分清晰,可以好好看看,我发现现在我的思维越来越死了,大概生锈了吧,每次看到这类题我就心生畏惧。

代码

#include <iostream>
#include <cstdio>

#define ll long long

using namespace std;

const ll MAXN = 1e5 + 10;
const ll MOD = 1e9 + 7;
const ll INV_2 = 5e8 + 4;

ll n, m, ans;
ll prime[MAXN];
bool flag[MAXN];

ll qpow(ll x, ll y)
{
    if (y == 1)
    {
        return x;
    }
    ll t = qpow(x, y / 2);
    if (y % 2 == 0)
    {
        return t * t % MOD;
    }
    return t * t % MOD * x % MOD;
}

void init()
{
    for (int i = 2; i < MAXN; i++)
    {
        if (!flag[i])
        {
            prime[++prime[0]] = i;
        }
        for (int j = 1; j <= prime[0]; j++)
        {
            if (i * prime[j] > MAXN)
            {
                break;
            }
            flag[i * prime[j]] = 1;
            if (i % prime[j] == 0)
            {
                break;
            }
        }
    }
}

int main()
{
    init();

    scanf("%lld", &n);

    ll x, y;
    while (n--)
    {
        scanf("%lld", &x);

        ans = 1;
        y = x;
        for (int i = 1; prime[i] * prime[i] <= x; i++)
        {
            if (x % prime[i])
            {
                continue;
            }
            ll t = 0, k = 1;
            while (x % prime[i] == 0)
            {
                x /= prime[i];
                t++;
            }
            k += prime[i] * (qpow(prime[i], 2 * t) - 1) % MOD * qpow(prime[i] + 1, MOD - 2) % MOD;
            ans = ans * k % MOD;
        }

        ll k = (1 + (x - 1) * x) % MOD;
        ans = ans * k % MOD;
        ans--;
        ans = (ans * y % MOD * INV_2 % MOD + y) % MOD;

        printf("%lld\n", ans);
    }

    return 0;
}