题意是求:

    $\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 + ;
const int Maxn = 1e6; int testCase, pCnt = , pri[N];
ll h[N], phi[N];
bool np[N]; template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for(; ch > ''|| ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} void sieve() {
phi[] = 1LL;
for(int i = ; i <= Maxn; i++) {
if(!np[i]) pri[++pCnt] = i, phi[i] = i - ;
for(int j = ; j <= pCnt && pri[j] * i <= Maxn; j++) {
np[i * pri[j]] = ;
if(i % pri[j] == ) {
phi[i * pri[j]] = phi[i] * pri[j];
break;
}
phi[i * pri[j]] = phi[i] * (pri[j] - );
}
} for(int i = ; i <= Maxn; i++) {
ll now = phi[i] * i / ;
if(i == ) 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 ;
}

———————————————————————————————————————————————————

upd:

去看了一下题解,发现其实可以线性筛$h(i) $,感觉很神仙。

下文中的$h(d) = \sum_{t | d} \phi (t) * t$

因为$\phi (t)$和$t = N(t)$都是积性函数,所以$\phi (t) * t$也是积性函数,那么$h(i)$就相当于$\phi(i) * i$与$1$的卷积,所以$h(i)$也是积性函数,可以线性筛。

  $h(p) = (p - 1) * p + 1 = p^2 - p + 1$

  $h(p^k) = h(p^k) = \sum_{i = 0}^{k}p^i * \phi (p^i) = p^2\sum_{i = 0}^{k - 1}p^i * \phi (p^i) - p + 1$

因为$\phi (p) = p - 1$,而$\phi (p^k) = \phi (p^{k - 1}) * p = (p - 1) * p^{k - 1}$,所以相当于多乘了一个$p$,把它减掉,然后加上第一项$1$。

最后算答案的时候注意到这时候$\phi (1)$是取$2$的,所以最后输出$\frac{(h(n) + 1)}{2}$。

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

不想实现。

SPOJ LCMSUM - LCM Sum的更多相关文章

  1. SP5971 LCMSUM - LCM Sum

    一个基于观察不依赖于反演的做法. 首先 \(\rm lcm\) 是不好算的,转化为计算 \(\rm gcd\) 的问题,求: \[\sum\limits_{i = 1} ^ n \frac{in}{\ ...

  2. 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) ...

  3. 数位DP:SPOJ KPSUM - The Sum

    KPSUM - The Sum One of your friends wrote numbers 1, 2, 3, ..., N on the sheet of paper. After that ...

  4. SPOJ:Elegant Permuted Sum(贪心)

    Special Thanks: Jane Alam Jan*At moment in University of Texas at San Antonio - USA You will be give ...

  5. SPOJ 3693 Maximum Sum(水题,记录区间第一大和第二大数)

    #include <iostream> #include <stdio.h> #include <algorithm> #define lson rt<< ...

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

    给我们n个数,然后有m个询问,每个询问为L,R,询问区间[L,R]的最大最小值,最小公约数,最大公约数,和,异或,或,且 这些问题通通可以用RMQ的思想来解决. 以下用xor来作为例子 设dp[i][ ...

  7. gcd套路变换

    gcd套路变换 GCD https://www.luogu.org/problem/P2568 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. $ 1& ...

  8. X000011

    P1890 gcd区间 \(\gcd\) 是满足结合律的,所以考虑用 ST 表解决 时间复杂度 \(O((n\log n+m)\log a_i)\) 考虑到 \(n\) 很小,你也可以直接算出所有的区 ...

  9. 初等数论学习笔记 III:数论函数与筛法

    初等数论学习笔记 I:同余相关. 初等数论学习笔记 II:分解质因数. 1. 数论函数 本篇笔记所有内容均与数论函数相关.因此充分了解各种数论函数的名称,定义,符号和性质是必要的. 1.1 相关定义 ...

随机推荐

  1. C# 之二进制序列化

    序列化:又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制.其目的是以某种存储形成使自定义对象持久化,或者将这种对象从一个地方传输到另一个地方. 一般有三种方式:1.是使用BinaryF ...

  2. HihoCoder1329 平衡树·Splay(附STL版)

    输入 第1行:1个正整数n,表示操作数量,100≤n≤200,000 第2..n+1行:可能包含下面3种规则: 1个字母'I',紧接着1个数字k,表示插入一个数字k到树中,1≤k≤1,000,000, ...

  3. C#托管代码、非托管代码及回收机制

    网上找了下相关文字,发现一些很不错的,转过来,方便以后查看 托管代码 托管代码就是Visual Basic .NET和C#编译器编译出来的代码.编译器把代码编译成中间语言(IL),而不是能直接在你的电 ...

  4. 使用python实现两个文件夹里文件的对比(包含内容的对比)

    #-*-coding:utf-8-*- #=============================================================================== ...

  5. 使用.NET中的XML注释(一) -- XML注释标签讲解

    一.摘要 .Net允许开发人员在源代码中插入XML注释,这在多人协作开发的时候显得特别有用. C#解析器可以把代码文件中的这些XML标记提取出来,并作进一步的处理为外部文档. 这篇文章将展示如何使用这 ...

  6. bzoj 1016 [JSOI2008]最小生成树计数——matrix tree(相同权值的边为阶段缩点)(码力)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1016 就是缩点,每次相同权值的边构成的联通块求一下matrix tree.注意gauss里的 ...

  7. WCF svcutil工具

    通过SvcUtil.exe生成客户端代码和配置 WCF服务调用通过两种常用的方式:一种是借助代码生成工具SvcUtil.exe或者添加服务引用的方式,一种是通过ChannelFactory直接创建服务 ...

  8. malloc 动态分配内存

    很久没有学习C了,复习下,有时候觉的C特别优美,学习算法和数据结构最佳选择. #include "stdafx.h" #include<stdlib.h> int ma ...

  9. jhipster初接触

    在Windows7部署之前把几个依赖下了 jdk:1.80 Maven :3.3.9 git:2.14.1 npm:唯一要注意的就是配置一个阿里的镜像,不然慢的你崩溃 Yeoman: npm inst ...

  10. vue中父子组件传递信息实现

    为了能够在父子组件中实现双向控制,需要以下的步骤: 第一步:子组件中挖坑 (1)在需要父组件填充具体内容的地方挖坑,方式为 <slot name="message">& ...