[SPOJ 5971] LCMSum 莫比乌斯反演

题意

  $t$ 组询问, 每组询问给定 $n$ , 求 $\sum_{k = 1} ^ n [n, k]$ .

  $t \le 300000, n \le 1000000$ .

一些常用的式子以及证明

  $\phi(n) = \sum_{d = 1} ^ n [(d, n) = 1]$ .

  说明 用数学语言进行描述不大于 $n$ 的与 $n$ 互质的数的个数.

  $n = \sum_{d | n} phi(d)$ .

  证明 对分数 $\frac{i}{n} , 1 \le i \le n$ 的个数算两次.

  $[n = 1] = \sum_{d | n} \mu(d)$ .

  证明 设 $n = \prod_{k = 1} ^ m a_k ^ {b_k}$ .

  $\sum_{d | n} \mu(d) = \sum_{k = 0} ^ m \binom{m}{k} {(-1)}^k = 0^m = [m = 0] = [n = 0]$ .

  $\sum_{d | n} [(d, n) = 1] d = \frac{ n \phi(n) + [n = 1] }{2}$ .

  证明 若 $(i, n) = 1$ , 则 $(i, n-i) = 1$ , 两个相加构成 $n$ , 一共有 $\frac{ \phi(n) }{2}$ 对.

  当 $n = 1$ 时, 需要特殊处理.

分析

  $$\begin{aligned} \sum_{k = 1} ^ n [k, n] & = n \sum_{k = 1} ^ n \frac{k}{(k, n)} \\ & = n \sum_{p | n} \frac{1}{p} \sum_{k = 1} ^ n k [p | k] [(k, n) = p] \\ & = n \sum_{p | n} ^ n \frac{1}{p} \sum_{k = 1} ^ {\frac{n}{p}} kp [(k, \frac{n}{p}) = 1] & = n \sum_{p | n} ^ n \sum_{k = 1} ^ {\frac{n}{p}} k [(k, \frac{n}{p}) = 1] & = n \sum_{p | n} \frac{p \phi(p) + [p = 1]}{2} \end{aligned} $$ .

  线性筛 $\phi$ 函数, 调和级数的复杂度进行预处理.

实现

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cctype>

#define F(i, a, b) for (register int i = (a); i <= (b); i++)

#define LL long long

const int N = 1000000;

bool v[N+5]; int tot, p[N+5], phi[N+5];
LL ans[N+5];

inline int rd(void) {
    int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1;
    int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f;
}

int main(void) {
    #ifndef ONLINE_JUDGE
        freopen("bzoj2226.in", "r", stdin);
        freopen("bzoj2226.out", "w", stdout);
    #endif

    v[1] = false, phi[1] = 1;
    F(i, 2, N) {
        if (!v[i]) phi[ p[++tot] = i ] = i-1;
        for (int j = 1; j <= tot && i * p[j] <= N; j++) {
            v[i * p[j]] = true;
            if (i % p[j] != 0)
                phi[i * p[j]] = phi[i] * phi[p[j]];
            else { phi[i * p[j]] = phi[i] * p[j]; break; }
        }
    }

    F(i, 1, N) {
        LL t = (1LL * i * phi[i] + (i == 1)) >> 1;
        for (int j = i; j <= N; j += i)
            ans[j] += t;
    }
    F(i, 1, N) ans[i] *= i;

    int t = rd();
    F(i, 1, t) {
        int n = rd();
        printf("%lld\n", ans[n]);
    }

    return 0;
}
时间: 2024-10-07 15:14:45

[SPOJ 5971] LCMSum 莫比乌斯反演的相关文章

【BZOJ2226】[Spoj 5971] LCMSum 莫比乌斯反演(欧拉函数?)

[BZOJ2226][Spoj 5971] LCMSum Description Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Least Common Multiple of the integers i and n. Input The first line contains T the number of test cases. Each of the n

BZOJ 2226: [Spoj 5971] LCMSum( 数论 )

∑lcm(i,n) = ∑ i*n/(i,n) = ∑d|n∑(x,n)=d x*n/d = ∑d|n∑(t,n/d)=1t*n = n∑d|nf(d). f(d)表示1~d中与d互质的数的和, 即f(d) = d*φ(d)/2(d>=2). 然后O(n)筛φ, 每次询问暴力算即可...最大是100w,sqrt(100w)=1000内的质数是168个, 所以复杂度是O(n + T*168), 可以AC  ----------------------------------------------

[BZOJ2226][SPOJ5971]LCMSum(莫比乌斯反演)

2226: [Spoj 5971] LCMSum Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1949  Solved: 852[Submit][Status][Discuss] Description Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Least Common Multiple of the in

bzoj2226[Spoj 5971] LCMSum

题目大意:给定T(10^5)组数据,每次给出n(10^6),求lcm(i,n){1<=i<=n}的和 一眼看上去就是一道数学题--蒟蒻数学太差思路略微诡异--我想着能不能nlogn直接把所有答案算出来,然后yy了一下-- 设F[n]为所求的值,f[n]为小于n的质数的和,我们考虑到lcm(a,b)=ab/gcd(a,b),那么我们可以去枚举gcd,对于一个n的因数d,在1到n中和n最大公因数为d的数对于F[n]的贡献就显而易见了,即F[n]+=n*d*f[n/d],这样可以nlogn求出 对于

A - Visible Lattice Points SPOJ - VLATTICE 容斥原理/莫比乌斯反演

Consider a N*N*N lattice. One corner is at (0,0,0) and the opposite one is at (N,N,N). How many lattice points are visible from corner at (0,0,0) ? A point X is visible from point Y iff no other lattice point lies on the segment joining X and Y. Inpu

BZOJ 2226: [Spoj 5971] LCMSum

Description 求\(\sum_{i=1}^n[i,n],n\leqslant 10^6,T\leqslant 3\times 10^5\) Solution 数论.. \(\sum_{i=1}^n[i,n]\) \(=n\sum_{i=1}^n\frac{i}{(i,n)}\) \(=n\sum_{d|n}\sum_{i=1}^{\frac{n}{d}}[(i,\frac{n}{d})=1]i\) 后面这个其实可以直接算出来 \(\sum_{i=1}^n[(i,n)=1]i=\sum_

Visible Lattice Points SPOJ - VLATTICE 三维+莫比乌斯反演

#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1e7+10; int vis[maxn]; int mu[maxn]; int prime[maxn]; int tot=0; int sum1[maxn]; int sum2[maxn]; void get_mu() { mu[1]=1; vis[1]=1; for(int i=2;i<maxn;i++) { if(!vis

SPOJ VLATTICE Visible Lattice Points 莫比乌斯反演 难度:3

http://www.spoj.com/problems/VLATTICE/ 明显,当gcd(x,y,z)=k,k!=1时,(x,y,z)被(x/k,y/k,z/k)遮挡,所以这道题要求的是gcd(x,y,z)==1的个数+{(x,y,0)|gcd(x,y)==1}的个数+3{(0,0,1),(0,1,0),(1,0,0)} 现在不去管最后的三个坐标轴上的点, 设f(i)=|{(x,y,0)|gcd(x,y)==i}|*3+|{(x,y,z)|gcd(x,y,z)==i}|,也就是不在坐标轴上且

spoj 4491 莫比乌斯反演

题意: 给出a,b,求gcd(x,y)=prime的方案数,其中:1 <= x <= a && 1 <= y <= b 限制: 1 <= a,b <= 1e7 思路: 先把问题拆成一个一个来考虑,然后问题就变成gcd(x,y)=k的方案数. 设f(k)为gcd(x,y)=k的方案数, 设F(k)为gcd(x,y)为k的倍数的方案数,显然F(k)=floor(a/k)*floor(b/k). 由莫比乌斯反演得: f(k)=mu[1]*F[k]+mu[2]*