SPOJ LCMSUM - LCM Sum

题意是求:

    $\sum_{i = 1}^{n}lcm(i, n)$

    $= \sum_{i = 1}^{n}\frac{ni}{gcd(i, n)}$

    $= n\sum_{i = 1}^{n}\frac{i}{gcd(i, n)}$

    $= n\sum_{d|n}\sum_{i = 1}^{n}d*[gcd(i, n)==d]$

    $= n\sum_{d|n}\sum_{i = 1}^{\frac{n}{d}}i*[gcd(i, \frac{n}{d})==1]$

    $= n\sum_{d|n}\sum_{i = 1}^{d}i*[gcd(i, d)==1]$

设$h(d) = \sum_{i = 1}^{d}i*[gcd(i, d)==1]$,其实是求在$1,2,3...d$的范围内与$d$互质的数的总和,当$d>1$时,它就等于$\frac{\phi (d) * d}{2}$

证明:

    因为$gcd(i, d) == 1$,那么也有$gcd(d - i, d) == 1$,所以假如$i$与$d$互质,那么$d - i$也与$d$互质,它们的和是$d$,也就是说在$1, 2, 3, ..., d$中,这样的数对一共有$\frac{\phi (d)}{2}$个,每一对的和是$d$,所以$h(d) = \frac{\phi (d) * d}{2}$

$h(1)$当然是等于$1$的。

这样我们线性筛出欧拉函数$\phi (i)$,然后再暴力算$h(i)$,最后询问的时候输出$h(n) * n$.

时间复杂度是$O(MaxNlogMaxN + T)$。

Code:

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;

const int N = 1e6 + 5;
const int Maxn = 1e6;

int testCase, pCnt = 0, pri[N];
ll h[N], phi[N];
bool np[N];

template <typename T>
inline void read(T &X) {
    X = 0; char ch = 0; T op = 1;
    for(; ch > ‘9‘|| ch < ‘0‘; ch = getchar())
        if(ch == ‘-‘) op = -1;
    for(; ch >= ‘0‘ && ch <= ‘9‘; ch = getchar())
        X = (X << 3) + (X << 1) + ch - 48;
    X *= op;
}

void sieve() {
    phi[1] = 1LL;
    for(int i = 2; i <= Maxn; i++) {
        if(!np[i]) pri[++pCnt] = i, phi[i] = i - 1;
        for(int j = 1; j <= pCnt && pri[j] * i <= Maxn; j++) {
            np[i * pri[j]] = 1;
            if(i % pri[j] == 0) {
                phi[i * pri[j]] = phi[i] * pri[j];
                break;
            }
            phi[i * pri[j]] = phi[i] * (pri[j] - 1);
        }
    }

    for(int i = 1; i <= Maxn; i++) {
        ll now = phi[i] * i / 2;
        if(i == 1) now = 1LL;
        for(int j = i; j <= Maxn; j += i)
            h[j] += now;
    }
}

int main() {
    sieve();
    for(read(testCase); testCase--; ) {
        int n; read(n);
        printf("%lld\n", 1LL * n * h[n]);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/CzxingcHen/p/9687956.html

时间: 2024-10-27 02:21:08

SPOJ LCMSUM - LCM Sum的相关文章

spoj LCMSUM sigma(lcm(i,n));

Problem code: LCMSUM 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 next T lines contain

SPOJ BALLSUM - Ball sum

题目链接:http://www.spoj.com/problems/BALLSUM/ 题目大意:问从N个数中选两个数和小于等于K的概率值,用分数表示. 解题思路:假设要选择小于等于5的数字,那么可选项有(1,4) (1,3) (1,2) (2,3),可以发现实际上是k-2 + k-4 +...当该项为0时停止即可.N个数里面选择两个可以直接n(n-1)/2,表示成分数则可以同除以GCD. 代码: 1 const int maxn = 1e6 + 5; 2 ll n, k; 3 4 ll gcd(

[数位统计] spoj 1433 The sum

题意:对于数加一位减一位,给定N,求1~N的和. 例子12=1-2+3-4......-1+2=5 思路: 个人思路可能比较复杂,但是思路还是比较清晰的. 首先我们把一个数N分成两个部分,比如4568=1~999+1000~4568,567=1~99+100~567 也就是整百整千的数我们可以递推算出来,虽然找规律也是可以的~ 就是1~999=1~99+100~999. 这样算的话 其实就解决了最后计算的问题,更能统一函数. 然后其实我们可以发现,位数是奇数的数,除了个位前面的数是两两抵消的.

询问任意区间的min,max,gcd,lcm,sum,xor,or,and

给我们n个数,然后有m个询问,每个询问为L,R,询问区间[L,R]的最大最小值,最小公约数,最大公约数,和,异或,或,且 这些问题通通可以用RMQ的思想来解决. 以下用xor来作为例子 设dp[i][j]为以i开头的,长度为2^j的区间的所有值得异或 那么dp[i][j] = dp[i][j-1] xor dp[i+(1<<(j-1))][j-1] 这样,运用动态规划的思想,我们可以在nlogn的时间复杂度内算出以任意点开头的,长度为1,2,4,8...2^j 的区间的异或值. 那么询问任意区

数论十题

数论十题 Problem Zero:[neerc2011]Gcd guessing game 现在有一个数x,1 ≤ x≤ n,告诉你n,每次你可以猜一个数y,如果x==y则结束,否则返回gcd(x,y),问最少只要几次就可以保证猜出答案. 本题纯属娱乐.仅仅是一个GCD的游戏,跑题了. 因为本题要求最坏情况,我们直观地猜想就是每次返回都是1.由于答案有可能是质数,而判定一个数,必须要把含有这个质因子的数问一遍.于是,我们引出这样一个思路,将所有1-n的质数分组,每组的积<=n,答案就是组数.

(转载)有关反演和gcd

tips : 积性函数 F (n) = Π F (piai ) 若F (n), G (n)是积性函数则 F (n) * G (n) Σd | n F (n) 是积性函数 n = Σd | n  φ (d) 1 = Σd | n  μ (d) Σgcd (i, n) = 1 i = n * φ (n) / 2 Problem1 F (n) = Σ1<= i <= n gcd(i, n), n <= 1000000 Sol 枚举结果 F (n) = Σd | n d * Σgcd (i, n

51Nod 最大公约数之和V1,V2,V3;最小公倍数之和V1,V2,V3

1040 最大公约数之和 给出一个n,求1-n这n个数,同n的最大公约数的和.比如:n = 6 1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15 输入 1个数N(N <= 10^9) 输出 公约数之和 输入样例 6 输出样例 15 题解 \[ \sum_{i=1}^n\gcd(i,n)=\sum_{d|n}d\varphi(n) \] 暴力搞就行了. 1188 最大公约数之和 V2 给出一个数N,输出小于等于N的所有数,两两之间的最大公约数之和. 相当于计

数位DP小结

如果以下错的地方,谢谢提出. 1.HDU - 2089 不要62 解题思路:这题的限制条件是不能出现4,和数字中不能包含62,那么就对这两个进行特判即可 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define N 12 int n, m; int dp[N][N]; int data[N]; //zero_flag是前导零的标记,为0时表示有前导0 //bor

CodeForces 55D Beautiful numbers

Beautiful numbers 题目链接 Description Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just