HYSBZ 3944 Sum

来源:互联网 发布:手机贵金属软件 编辑:程序博客网 时间:2024/05/17 22:15

HYSBZ 3944 Sum

题目描述:

输入正整数 N (N2311) ,求 Ni=1ψ(i)Ni=1μ(i)

题解:

杜教筛模板题。

以欧拉函数为例:

i=1Ndiψ(d)=i=1N(ψ×1)(i)=N(N+1)2

F(x) 表示 xi=1ψ(i) ,那么又有
i=1Ndiψ(d)=id=1Nd=1Nidψ(d)=k=1Nd=1Nkψ(d)=k=1NF(Nk)

所以
F(N)=N(N+1)2i=2NF(Nk)

预处理出前 MAXN23 的答案,然后记忆化搜索即可。对于莫比乌斯函数的推到同理。

题目链接: vjudge 原网站

代码:

#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define MAXN 5000007#define MAXP MAXN / 10#define MAXM 200007static int T, pr_tot, prime[MAXP];static bool npr[MAXN], vis_phi[MAXM], vis_mu[MAXM];static long long N;static long long phi[MAXN], mu[MAXN], mem_phi[MAXM], mem_mu[MAXM];long long solve_phi(long long x){    if (x < MAXN) return phi[x];    if (vis_phi[N / x]) return mem_phi[N / x];    long long ans = (x + 1) * x / 2;    for (long long i = 2, last; i <= x; i = last + 1)    {        last = x / (x / i);        ans -= (last - i + 1) * solve_phi(x / i);    }    return vis_phi[N / x] = 1, mem_phi[N / x] = ans;}long long solve_mu(long long x){    if (x < MAXN) return mu[x];    if (vis_mu[N / x]) return mem_mu[N / x];    long long ans = 1;    for (long long i = 2, last; i <= x; i = last + 1)    {        last = x / (x / i);        ans -= (last - i + 1) * solve_mu(x / i);    }    return vis_mu[N / x] = 1, mem_mu[N / x] = ans;}int main(){    phi[1] = mu[1] = 1;    for (int i = 2; i < MAXN; i++)    {        if (!npr[i])            prime[pr_tot++] = i, phi[i] = i - 1, mu[i] = -1;        for (int j = 0; j < pr_tot && (long long)i * prime[j] < MAXN; j++)        {            npr[i * prime[j]] = 1;            if (i % prime[j])            {                phi[i * prime[j]] = phi[i] * (prime[j] - 1);                mu[i * prime[j]] = -mu[i];            }            else            {                phi[i * prime[j]] = phi[i] * prime[j];                mu[i * prime[j]] = 0;                break;            }        }    }    for (int i = 1; i < MAXN; i++)        phi[i] += phi[i-1], mu[i] += mu[i-1];    for (scanf("%d", &T); T; T--)    {        scanf("%lld", &N);        memset(vis_phi, 0, sizeof(vis_phi));        memset(vis_mu, 0, sizeof(vis_mu));        printf("%lld %lld\n", solve_phi(N), solve_mu(N));    }    return 0;}

提交记录(AC / Total = 1 / 6):

Run ID Remote Run ID Time(ms) Memory(kb) Result Submit Time 8729112 1988730 4608 80512 RE 2017-04-10 10:44:56 8729334 1988859 4972 102388 RE 2017-04-10 11:41:49 8729349 1988883 11104 80644 TLE 2017-04-10 11:47:29 8729386 1988918 0 174116 MLE 2017-04-10 12:01:50 8729427 1988928 548 89300 WA 2017-04-10 12:10:43 8729435 1988930 10964 89300 AC 2017-04-10 12:13:44
0 0
原创粉丝点击