题意

多组询问,每次给定 \(n\) ,求:\(\sum_{i=1}^nlcm(i,n)\) 。

  • \(\rm T \leq 3\times 10^4\ ,n \leq 10^6\)。

分析

  • 推式子:

\[\sum_{i=1}^n{\frac{in}{gcd(i,n)}}
\]

  • 枚举 \(gcd\) :

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

\[n\sum_{d|n}{\sum_{i=1}^{\frac{n}{d}}[i\perp \frac{n}{d}]i}
\]

\[n\sum_{d|n}{\sum_{i=1}^d{[i\perp d]i}}
\]

  • 对于后面的求和可以看成函数 \(f_d\) ,表示所有和 \(d\) 互质的数字之和。

  • 根据辗转相减可以得到 \(gcd(i,d)=gcd(d-i,d)\) ,表明所有与 \(d\) 互质的数字可以两两配对得到 \(d\) 。

  • 所以 \(f_d=\frac{\varphi(d)*d}{2}\) 。

  • 处理 \(\varphi\) 的时间 \(O(n)\) 加上单次处理的时间 \(O(\sqrt n)\),总时间复杂度为 \(O(2n)\) 。

技巧:辗转相减的使用

代码

#include<bits/stdc++.h>
using namespace std;
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].last,v=e[i].to)
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pb push_back
typedef long long LL;
inline int gi(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-48;ch=getchar();}
return x*f;
}
template<typename T>inline bool Max(T &a,T b){return a<b?a=b,1:0;}
template<typename T>inline bool Min(T &a,T b){return b<a?a=b,1:0;}
const int N=1e6 + 7;
int T,pric,n;
int phi[N],pri[N],vis[N];
LL f[N];
void pre(int Num){
phi[1]=1;int to;
for(int i=2;i<=Num;++i){
if(!vis[i]) { phi[i]=i-1,pri[++pric]=i;}
for(int j=1;j<=pric&&(to=i*pri[j])<=Num;++j){
vis[to]=1;
if(i%pri[j]==0){
phi[to]=phi[i]*pri[j];
break;
}
phi[to]=phi[i]*phi[pri[j]];
}
}
}
int main(){
T=gi();
pre(1000000);
f[1]=1;
for(int i=2;i<=1000000;++i) f[i]=1ll*phi[i]*i/2;
while(T--){
n=gi();LL ans=0;
int l=1,r=1000;
while(l<r){
int mid=l+r+1>>1;
if(mid*mid<=n) l=mid;
else r=mid-1;
}
for(int i=1;i<=l;++i)if(n%i==0){
ans+=f[i];
if(i*i!=n)
ans+=f[n/i];
}
printf("%lld\n",ans*n);
}
return 0;
}

[Luogu1891]疯狂LCM[辗转相减法]的更多相关文章

  1. luogu1891 疯狂lcm ??欧拉反演?

    link 给定正整数N,求LCM(1,N)+LCM(2,N)+...+LCM(N,N). 多组询问,1≤T≤300000,1≤N≤1000000 \(\sum_{i=1}^nlcm(i,n)\) \( ...

  2. Alice and Bob 要用到辗转相减

    Alice and BobTime Limit: 1 Sec  Memory Limit: 64 MBSubmit: 255  Solved: 43 Description Alice is a be ...

  3. bzoj 2852: 强大的区间 辗转相除

    2852: 强大的区间 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 45  Solved: 12[Submit][Status][Discuss] D ...

  4. (中等) CF 585C Alice, Bob, Oranges and Apples,矩阵+辗转相除。

    Alice and Bob decided to eat some fruit. In the kitchen they found a large bag of oranges and apples ...

  5. BZOJ.4031.[HEOI2015]小Z的房间(Matrix Tree定理 辗转相除)

    题目链接 辗转相除解行列式的具体实现? 行列式的基本性质. //864kb 64ms //裸的Matrix Tree定理.练习一下用辗转相除解行列式.(因为模数不是质数,所以不能直接乘逆元来高斯消元. ...

  6. Luogu4111 [HEOI2015]小Z的房间 (矩阵树,辗转相除高斯消元)

    除法不能用于同余系,要辗转相除.注意不能加入柱子到矩阵. #include <iostream> #include <cstdio> #include <cstring& ...

  7. 数据结构与算法C++描述学习笔记1、辗转相除——欧几里得算法

    前面学了一个星期的C++,以前阅读C++代码有些困难,现在好一些了.做了一些NOI的题目,这也是一个长期的目标中的一环.做到动态规划的相关题目时发现很多问题思考不通透,所以开始系统学习.学习的第一本是 ...

  8. POJ 2348 Euclid's Game(辗转相除博弈+自由度分析)

    题目链接:http://poj.org/problem?id=2348 题目大意:给你两个数a,b,Stan和Ollie轮流操作,每次可以将较大的数减去较小的数的整数倍,相减后结果不能小于0,谁先将其 ...

  9. P1891 疯狂LCM

    \(\color{#0066ff}{ 题目描述 }\) 众所周知,czmppppp是数学大神犇.一天,他给众蒟蒻们出了一道数论题,蒟蒻们都惊呆了... 给定正整数N,求LCM(1,N)+LCM(2,N ...

随机推荐

  1. Java 系统学习梳理_【All】

    Java基础 1. Java学习---JDK的安装和配置 2. Java学习---Java代码编写规范 2. Java学习---HashMap和HashSet的内部工作机制 3. Java学习---J ...

  2. Linux系统重要的开机自启动的服务

    重要的开机自启动的服务 1.sshd  连接Linux服务器是需要用到的服务程序    2.rsyslog 操作日志的一种机制                系统日志:/var/log/message ...

  3. Linux ntpdate命令详解

    ntpdate命令用于同步更新互联网时间,或者NTP服务器时间 NTP服务器[Network Time Protocol(NTP)]是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源 ...

  4. ArcGIS Engine开发基础总结(一)

    标准Engine功能 地图浏览    地图制作 数据查询 数据分析 及 所有的开发控件 —MapControl, PageLayout, Toolbar, TOC, ArcReader 对所有矢量和栅 ...

  5. 【接口】常见接口集合(返回JSON)

    转<JSON校验网站…>http://www.bejson.com/go.html?u=http://www.bejson.com/webInterface.html 这里为大家搜集了一些 ...

  6. 推荐一个好用的以多tab标签方式打开windows CMD的工具

    最近我在做基于nodejs的微服务开发,需要在windows命令行里启动很多微服务.我的windows 10任务栏是这样子的: 我想找一款能像下图Chrome标签页这样打开windows 10 CMD ...

  7. Python简单的购物车小代码

    # -*- coding: utf-8 -*- # @Time : 2018-05-31 14:56 # @Author : 超人 # @Email : huxiaojiu111@gmail.com ...

  8. debian 7上安装svn

    1.在终端中直接输入  sudo apt-get install subversion,选择安装即可 2.查看版本命令 svnserve --version(更多命令直接键入svnserve --he ...

  9. redis开启远程连接访问和需要密码的方法

    redis默认是不能远程访问的,如果希望多台机子共用redis数据库,那就需要开启redis远程连接访问.既然可以远程连接了,那就需要密码登陆,否则不安全.下面是具体的方法,按照步骤一步一步来就OK了 ...

  10. 小白学svn

    该博客是本人第一次在自己的电脑中部署svnserver后的一些心得,希望对小白们有所帮助.尽管本人之前有使用svn开发的经验,可是那都是使用百度开发人员平台的,我一直以为在自己的电脑中弄svnserv ...