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 + ;
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的更多相关文章
- SP5971 LCMSUM - LCM Sum
一个基于观察不依赖于反演的做法. 首先 \(\rm lcm\) 是不好算的,转化为计算 \(\rm gcd\) 的问题,求: \[\sum\limits_{i = 1} ^ n \frac{in}{\ ...
- 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) ...
- 数位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 ...
- SPOJ:Elegant Permuted Sum(贪心)
Special Thanks: Jane Alam Jan*At moment in University of Texas at San Antonio - USA You will be give ...
- SPOJ 3693 Maximum Sum(水题,记录区间第一大和第二大数)
#include <iostream> #include <stdio.h> #include <algorithm> #define lson rt<< ...
- 询问任意区间的min,max,gcd,lcm,sum,xor,or,and
给我们n个数,然后有m个询问,每个询问为L,R,询问区间[L,R]的最大最小值,最小公约数,最大公约数,和,异或,或,且 这些问题通通可以用RMQ的思想来解决. 以下用xor来作为例子 设dp[i][ ...
- gcd套路变换
gcd套路变换 GCD https://www.luogu.org/problem/P2568 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. $ 1& ...
- X000011
P1890 gcd区间 \(\gcd\) 是满足结合律的,所以考虑用 ST 表解决 时间复杂度 \(O((n\log n+m)\log a_i)\) 考虑到 \(n\) 很小,你也可以直接算出所有的区 ...
- 初等数论学习笔记 III:数论函数与筛法
初等数论学习笔记 I:同余相关. 初等数论学习笔记 II:分解质因数. 1. 数论函数 本篇笔记所有内容均与数论函数相关.因此充分了解各种数论函数的名称,定义,符号和性质是必要的. 1.1 相关定义 ...
随机推荐
- 【pandas】pandas.DataFrame.rename()---重置索引名称
官方文档 github地址 例子: 创建DataFrame ### 导入模块 import numpy as np import pandas as pd import matplotlib.pypl ...
- sklearn实践_普通线性回归
import pandas as pd import numpy as np import matplotlib.pyplot as plt data = pd.read_csv(r"C:\ ...
- 观后感|当幸福来敲门 The Pursuit of Happyness
更好的阅读体验请点击:当幸福来敲门 The Pursuit of Happyness 看到时光机点亮的那一刻,我想儿子克里斯托夫正在侏罗纪的世界内探险,看着山川河流,穿梭在恐龙的脚下,在山洞中安稳的度 ...
- 服务端缓存页面及IIS缓存设置
缓存信息基本概念 我们在看网页的header信息时,经常看到这几个参数:Expires.Cache-Control.Last-Modified.ETag,它们是RFC 2616(HTTP/1.1)协议 ...
- 使用POI导出excel基础篇
最近搞了下POI导出Excel,听说很多次,却是第一次搞. 在pom.xml中引入依赖 <dependency> <groupId>org.apache.poi</gro ...
- Linux网络编程学习路线
转载自:https://blog.csdn.net/lianghe_work/article 一.网络应用层编程 1.Linux网络编程01——网络协议入门 2.Linux网络编程02——无连接和 ...
- 把Azure专线从Class模式迁移到ARM模式
前面几篇文章介绍了Azure的ASM模式和ARM模式.很多用户已经在ASM模式下部署了Azure的专线服务,如果部署的应用是ARM模式,或ASM模式和ARM模式都有,就需要把ASM模式的专线迁移到AR ...
- TreeView 树节点的处理
TreeView 树节点的处理 using System; using System.Collections.Generic; using System.ComponentModel; using S ...
- Maven的Snapshot版本与Release版本
1. Snapshot版本代表不稳定.尚处于开发中的版本 2. Release版本则代表稳定的版本 3. 什么情况下该用SNAPSHOT? 协同开发时,如果A依赖构件B,由于B会更新,B应该使用SNA ...
- Java程序开发中的简单内存分析
首先说明内存总体分为了4个部分, 包括 1.stack segment (栈区存储基本数据类型的局部变量,对象的引用名) 2.heap segment(堆区,一般用于存储java中new 出来的对象) ...