「SPOJ5971」 LCMSUM - 数论数学

题目描述

求 \(\sum_{i=1}^nlcm(i,n)\)

\(T\) 组数据
\(1\le T\le 300000\)
\(1\le n\le 1000000\)

链接

bzoj 2226
luogu SP5971

题解

算法1(暴力)

直接暴力枚举 \(i\) ,计算 \(lcm\)
时间复杂度 \(O(Tnlogn)\)

算法2 (数论)

先不管最后一个,就变成了这个:
\[
\sum_{i=1}^{n-1}lcm(i,n)
\]
将 \(lcm\) 转化为 \(gcd\):
\[
Ans=\sum_{i=1}^{n-1}\frac{in}{gcd(i,n)}
\]
转化下,其实没有区别:
\[
Ans=\frac12\cdot 2\sum_{i=1}^{n-1}\frac{in}{gcd(i,n)}
\]
再次转化,倒着求和:
\[
Ans=\frac12\cdot(\sum_{i=1}^{n-1}\frac{in}{gcd(i,n)}+\sum_{i=n-1}^1\frac{in}{gcd(i,n)})
\]
因为 \(gcd(i,n)=gcd(n-i,i)\)
所以:
\[
Ans=\frac12\cdot(\sum_{i=1}^{n-1}\frac{in}{gcd(i,n)}+\sum_{i=n-1}^1\frac{in}{gcd(n-i,n)})
\]
然后我们发现分母相同于是合并:
\[
Ans=\frac12\cdot(\sum_{i=1}^{n-1}\frac{n^2}{gcd(i,n)})
\]
考虑枚举 \(gcd\) ,先算上 \(n\) :
\[
Ans=\frac12n\cdot\sum_{d|n}\frac{n}{d}\cdot \sum_{i=1}^{n}[gcd(i,n)==d]
\]
继续:
\[
Ans=\frac12n\cdot\sum_{d|n}\frac{n}{d}\cdot \sum_{i=1}^{\frac nd}[gcd(i,n)==1]
\]
发现后面的其实就是 \(\phi(\frac {n}d)\) :
\[
Ans=\frac12n\cdot\sum_{d|n}\frac{n}{d}\cdot\phi(\frac{n}d)
\]
然后等价于:
\[
Ans=\frac12n\cdot\sum_{d|n}d\cdot\phi(d)
\]
然后把多算的减掉:
\[
Ans=(\frac12n\cdot\sum_{d|n}d\cdot\phi(d))-\frac12n
\]
然后把少算的加回去:
\[
Ans=(\frac12n\cdot\sum_{d|n}d\cdot\phi(d))-\frac12n+n\=(\frac12n\cdot\sum_{d|n}d\cdot\phi(d))+\frac12n\=\frac12n\cdot((\sum_{d|n}d\cdot\phi(d))+1)
\]
于是就推完了
预处理时间复杂度是 \(O(nlogn)\) 的
但是有一种 \(O(n)\) 的方法,因为数据比较小,没有研究

#include <cstdio>
typedef int INT;
#define int long long
#define __R register

const int MAXN=1000005;

int q;
int n;
int f[MAXN],p[MAXN],phi[MAXN];
bool vis[MAXN];

template <typename T>
inline void read(T &x){
    int ch,fl=0;
    while (ch=getchar(),ch<48 || 57<ch) fl^=!(ch^45); x=(ch&15);
    while (ch=getchar(),47<ch && ch<58) x=(x<<1)+(x<<3)+(ch&15);
    if (fl) x=-x;
}

inline void sieve(){
    vis[0]=vis[1]=1; phi[1]=1;
    for (__R int i=2;i<MAXN;++i){
        if (!vis[i]){
            p[++p[0]]=i;
            phi[i]=i-1;
        }
        for (int j=1;j<=p[0] && i*p[j]<MAXN;j++){
            vis[i*p[j]]=1;
            if (i%p[j]==0){
                phi[i*p[j]]=phi[i]*p[j];
                break;
            } else{
                phi[i*p[j]]=phi[i]*(p[j]-1);
            }
        }
    }
    for (int i=1;i<MAXN;i++)
        for (int j=i;j<MAXN;j+=i)
            f[j]+=i*phi[i];
}

inline int solve(int x){
    return (f[x]+1)*x>>1;
}

INT main(){
    sieve();
    read(q);
    for (__R int x;q;--q){
        read(x);
        printf("%lld\n",solve(x));
    }
    return 0;
}

后记

数论题目真套路

原文地址:https://www.cnblogs.com/xuanyi/p/9490064.html

时间: 2024-12-29 11:44:36

「SPOJ5971」 LCMSUM - 数论数学的相关文章

「CodeForces-498C」Array and Operations(数论+网络流)

「CodeForces-498C」Array and Operations给定n个点和m个边集,每次操作可以将相连边的两个点值同时除以一个公约数,问最大操作次数 题意 给定一个长为$n$的数组,以及$m$对下标为$(a,b)$的点对,且满足下标a+b为奇数(即奇数点只与偶数点匹配),每次操作可以将同一组的两个数同时除以一个公约数,问最多能进行多少次操作. 解法 显然题目所给的是一个二分图. 对于每个质因数分开考虑.对于奇数点,向源点连接一个容量为该因子个数的边:对于偶数点,则向汇点建立一个容量为

大数据和「数据挖掘」是何关系?---来自知乎

知乎用户,互联网 244 人赞同 在我读数据挖掘方向研究生的时候:如果要描述数据量非常大,我们用Massive Data(海量数据)如果要描述数据非常多样,我们用Heterogeneous Data(异构数据)如果要描述数据既多样,又量大,我们用Massive Heterogeneous Data(海量异构数据)--如果要申请基金忽悠一笔钱,我们用Big Data(大数据) 编辑于 2014-02-2817 条评论感谢 收藏没有帮助举报作者保留权利 刘知远,NLPer 4 人赞同 我觉得 大数据

「网络流」

$Tasklist$ 无限之环 星际竞速 4823: 老C的方块 2007: 海拔 还有51nod上的 集合交易 「奇怪的游戏」:小学数学+最大流 如果不相等,算出来要多叠多少层,否则答案具有二分性.check用最大流 土兵占领:补集转化+最小割 转化为最多有多少士兵能同时给一行和一列作出贡献,然后最小割可以做 「紧急疏散」:增量+最大流 必须根据时间拆点,而不能每经过一个时间给终点流量+1,因为不能让后面的人占用前面的流量 狼抓兔子:最小割/对偶图 不管写最小割还是对偶图都是模板 「切糕」:最

「01」机器学习,到底在学些什么?

阅读 0 编辑文章 大家好,欢迎来到久违的机器学习系列,这是「美团」算法工程师带你入门机器学习 专栏的第一篇文章,不会太长,一半聊想法,一半聊干货.熟悉我的朋友可能知道,我以前的文章比较随意,涉及的内容极广,包括但不限于Python/Java/C/C++,网络编程,Hadoop等,但主要核心还是机器学习算法和数据科学相关的主题,这一点没变过. 最近认真总结和思考了之前的博客内容,决定将自己从入门到现在一路走来的学习经验和理解整理一番,帮助更多后来的小伙伴更好的入门,所以就有了这个系列.以前的知乎

「02」《机器学习经&amp;#183;天工开物篇》

上期导读:机器学习,到底在学些什么? 起源 故事要从上古神器差分机说起. 从古至今,所有的算法修炼和真气推演记录,全部要靠门派里的外门弟子手写,工序繁杂不说,还耗时良久,导致各大门派的修炼进度一直提不上来. 直到两百年前,神器大师查尔斯·巴贝奇开始了差分机的设计和制造,在后续大师的不断改良之后,终于实现了从真气计算到密文印刷的过程全部自动化,这样还可以避免人为误差,在那个时候,这是一个非常开创性的想法. ? 差分机使用有限差分法来机器计算多项式函数(一种真气运转模式)的值.有限差分方法是个简单但

「MoreThanJava」计算机发展史—从织布机到IBM

「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 不论新老朋友 我相信您都可以 从中获益.如果觉得 「不错」 的朋友,欢迎 「关注 + 留言 + 分享」,文末有完整的获取链接,您的支持是我前进的最大的动力! 一.织布机 | 一切的开端 如今代表智能现代的计算机与老式织布机的血缘关系超乎你的想象.无论是摆在写字台上的 台式机.塞在口袋里的 掌上电脑.

AC日记——「HNOI2017」单旋 LiBreOJ 2018

#2018. 「HNOI2017」单旋 思路: set+线段树: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define maxtree maxn<<2 int val[maxtree],tag[maxtree],L[maxtree],R[maxtree],mid[maxtree]; int op[maxn],ki[maxn],bi[maxn],cnt,size,n,ch[maxn]

「随笔」基于当下的思考

马德,说好的技术blog,变成日记本了... 下午的时候莫名其妙的感到很颓废,因为自己的不够强大感到忧虑和危机感十足.现在每每行走在技术的道路上,常觉得如履薄冰,如芒在背. 上大学之前和现在的心态其实差别挺大的,视野的开阔远远不止局限于自己的脚下.不过,这里的「上大学之前」只是一个时间描述词,并不觉得大学是最适合学习的地方,我很失望. 世界上的人无论性别,区域,宗教,兴趣爱好,总可以在互联网上找到志趣相同的人,总是可以不断打破自己的常识与惯性思维.总是有在相同领域比自己更强的人,挺好的. 关于知

「Unity」与iOS、Android平台的整合:3、导出的Android-Studio工程

本文属于「Unity与iOS.Android平台的整合」系列文章之一,转载请注明出处. Unity默认导出的是Android-Eclipse工程,毕竟Eclipse for Android开发在近一两年才开始没落,用户量还是非常巨大的. 个人认为AndroidStudio非常好用,能轻易解决很多Eclipse解决不了或者很难解决的问题. 所以我将Unity导出的Andoid工程分为Eclipse和AndroidStudio两部分. 不过我之后的相关内容都会使用AndroidStudio,希望依然