HDU 5942

$f(k)$表示k的因子数,$g(k)=2^{f(k)}$,那么$g(k)$表示的就是$k$的非平方以上因子的个数。
那么$g(k)=\sum_{d|k} \mu^2(k)$。
那么就是求$\sum_{i=1}^{n} \sum_{d|i} \mu^2(d)$。
$\sum_{d|i} \mu^2(k)=\sum_{d|i} \sum_{k^2|d} \mu(k)$,
交换sigma顺序。
$\sum_{k=1}^{\sqrt(n)} \mu(k) \sum_{d=1}^{\left \lfloor \frac{n}{k^2} \right \rfloor} \left \lfloor \frac{n}{k^2d} \right \rfloor$。

前面$O(\sqrt(n))$复杂度求,后面大数据分块求,小数据分块加记忆化。复杂度不会计算。。。

#include <bits/stdc++.h>

using namespace std;
const int mod = 1e9 + 7;
typedef long long ll;
ll n;
const int N = 1e6;
bool p[N + 5];
int prime[N + 5], top;
int mu[N + 5];
ll res;
ll f[N + 5];

void init() {
    memset(p, 0, sizeof p);
    mu[1] = 1;
    top = 0;
    for (int i = 2; i <= N; ++i) {
        if (!p[i]) {
            prime[++top] = i;
            mu[i] = -1;
        }
        for (int j = 1; j <= top; ++j) {
            if (i * prime[j] > N) break;
            p[i * prime[j]] = 1;
            if (i % prime[j] == 0) break;
            mu[i * prime[j]] = -mu[i];
        }
    }
}

ll calc(ll n) {
    if (n <= N && f[n]) return f[n];
    ll ret = 0;
    for (ll i = 1, lst; i <= n; i = lst + 1) {
        lst = n / (n / i);
        ret += (n / i) * (lst - i + 1);
        ret %= mod;
    }
    if (n <= N) f[n] = ret;
    return ret;
}

int main() {
    //freopen("in.txt","r",stdin);
    init();
    int T, cas = 1;
    memset(f, 0, sizeof f);
    for (cin >> T; T--;) {
        cin >> n;
        res = 0;
        for (ll i = 1; i * i <= n; i++) {
            if (mu[i]) {
                (res += mu[i] * calc(n / i / i) % mod) %= mod;
            }
        }
        res = (res % mod + mod) % mod;
        cout << "Case #" << cas++ << ": " << res << endl;
    }
    return 0;
}

转载于:https://www.cnblogs.com/foreignbill/p/7887340.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值