51nod-1227-平均最小公倍数
题意
定义 \(n\) 的平均最小公倍数:
\]
求
\]
\(n\le 10^9\) 。
分析
有趣的题,学到了一些东西。
我最开始不知道怎么都枚举gcd的时候是整除枚举,然后怎么都做不了。改求和指标为gcd的时候,直接从 1 到 \(n\) 枚举不是很正常的做法吗?于是就开始推………经过很久,答案变成了这个样子:
g(n)=\sum _{e|n}e\mu (e) \\
f(n)=\frac{n(n+1)(n+2)}{6}
\]
由于取底全部都是从 \(n\) 出发的,而且根据底合并的性质,可以用杜教筛来快速计算 \(g\) 的前缀和,分段计算,复杂度为 \(O(n^\frac{3}{4})\) 。
然后TLE了。
网上有一篇题解说可以直接从 \(L\) 到 \(R\) 计算,不需要算两次,我不是很懂怎么做;用杜教筛只能从前缀和出发吧 。
肯定是做法有点问题。于是去找题解。这题非常简单嘛!不用像我那样。
枚举一对互质的数,再取它们的倍数,比值是定值! 非常妙的方法啊!!!
\sum _{i=1}^n\sum _{j=1}^i\frac{j}{\gcd(i,j)}&=\sum _{i=1}^n\sum _{j=1}^i[\gcd(i,j)=1]\sum _{k=1}^{\lfloor\frac{n}{i}\rfloor}j \\
&=\sum _{i=1}^n\lfloor\frac{n}{i}\rfloor\sum _{j=1}^i[\gcd(i,j)=1]j
\end{aligned}
\]
右边的那个东西……不就是与 \(i\) 互质的数的和!由对称性,可以得到:
\]
于是就可以简单地用杜教筛求 \(\varphi(n)*n+[n==1]\) 的前缀和,分段计算啦!通过预处理,复杂度为 \(O(n^\frac{2}{3})\) 。
#include<bits/stdc++.h>
#include<tr1/unordered_map>
using namespace std;
using namespace std::tr1;
typedef long long giant;
const int q=1e9+7;
inline int Plus(int x,int y) {return ((giant)x+(giant)y)%q;}
inline int Sub(int x,int y) {return Plus(x,q-y);}
inline int Multi(int x,int y) {return (giant)x*y%q;}
inline int mi(int x,int y) {
int ret=1;
for (;y;y>>=1,x=Multi(x,x)) if (y&1) ret=Multi(ret,x);
return ret;
}
inline int inv(int x) {return mi(x,q-2);}
const int maxn=2e6+1;
const int i2=inv(2);
const int i6=inv(6);
bool np[maxn];
int p[maxn],ps=0,phi[maxn];
typedef unordered_map<int,int> Map;
Map PHI;
inline int sum(int n) {return Multi(Multi(n,n+1),i2);}
inline int f(int n) {return Multi(Multi(n,n+1),Multi((2ll*n+1)%q,i6));}
int g(int n) {
if (n<maxn) return phi[n];
Map::iterator it=PHI.find(n);
if (it!=PHI.end()) return it->second;
int &ret=PHI[n]=0;
for (int i=2,j;i<=n;i=j+1) {
j=n/(n/i);
ret=Plus(ret,Multi(Sub(sum(j),sum(i-1)),g(n/i)));
}
return ret=Sub(f(n),ret);
}
int calc(int n) {
int ret=0,last=0;
for (int i=1,j;i<=n;i=j+1) {
j=n/(n/i);
int x=Plus(g(j),1);
ret=Plus(ret,Multi(n/i,Sub(x,last)));
last=x;
}
return Multi(ret,i2);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
phi[1]=1;
for (int i=2;i<maxn;++i) {
if (!np[i]) p[++ps]=i,phi[i]=i-1;
for (int j=1,tmp;j<=ps && (tmp=i*p[j])<maxn;++j) {
np[tmp]=true;
if (i%p[j]==0) {
phi[tmp]=Multi(phi[i],p[j]);
break;
}
phi[tmp]=Multi(phi[i],phi[p[j]]);
}
}
for (int i=2;i<maxn;++i) phi[i]=Plus(phi[i-1],Multi(phi[i],i));
int L,R;
cin>>L>>R;
cout<<Sub(calc(R),calc(L-1))<<endl;
return 0;
}
51nod-1227-平均最小公倍数的更多相关文章
- 51NOD 1227 平均最小公倍数 [杜教筛]
1227 平均最小公倍数 题意:求\(\frac{1}{n} \sum_{i=1}^n lcm(n,i)\) 和的弱化版? \[ ans = \frac{1}{2}((\sum_{i=1}^n \su ...
- 51nod 1227 平均最小公倍数【欧拉函数+杜教筛】
以后这种题能用phi的就不要用mu-mu往往会带着个ln然后被卡常致死 把题目要求转换为前缀和相减的形式,写出来大概是要求这样一个式子: \[ \sum_{i=1}^{n}\sum_{j=1}^{i} ...
- 【51nod】1227 平均最小公倍数
题解 这个故事告诉们数论函数不要往分式上跑,你推不出来 好久没推式子了这么明显的转化我都忘了= = 首先\(A(n) = \frac{1}{n} \sum_{i = 1}^{n} \frac{i * ...
- 51 nod 1227 平均最小公倍数
原题链接 Lcm(a,b)表示a和b的最小公倍数,A(n)表示Lcm(n,i)的平均数(1 <= i <= n), 例如:A(4) = (Lcm(1,4) + Lcm(2,4) + Lcm ...
- 51NOD 1227:平均最小公倍数——题解
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1227 懒得打公式了,看这位的吧:https://blog.csdn.ne ...
- 【51Nod 1222】最小公倍数计数
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1222 求\([a,b]\)中的个数转化为求\([1,b]\)中的个数减去 ...
- 【51nod】1222 最小公倍数计数 莫比乌斯反演+组合计数
[题意]给定a和b,求满足a<=lcm(x,y)<=b && x<y的数对(x,y)个数.a,b<=10^11. [算法]莫比乌斯反演+组合计数 [题解]★具体 ...
- 【51Nod 1238】最小公倍数之和 V3
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1238 设\(A(n)=\sum\limits_{i=1}^n\frac{ ...
- 【51Nod 1190】最小公倍数之和 V2
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1190 \[ \begin{aligned} &\sum_{i=a ...
- 【51Nod 1363】最小公倍数之和
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1363 \[ \begin{aligned} &\sum_{i=1 ...
随机推荐
- 20155316 2016-2017-2 《Java程序设计》第10周学习总结
教材学习内容总结 Java和Android开发学习指南(第二版)第22章 Java 密码技术 教材学习中的问题和解决过程 1.什么叫柯克霍夫原则? 数据的安全基于密钥而不是算法的保密. 也就是说系统的 ...
- 9.15 DP合集水表
9.15 DP合集水表 显然难了一些啊. 凸多边形的三角剖分 瞄了一眼题解. 和蛤蛤的烦恼一样,裸的区间dp. 设f[i][j]表示i~j的点三角剖分最小代价. 显然\(f[i][i+1]=0,f[i ...
- 存一下emacs配置
(global-set-key [f9] 'compile-file)(global-set-key [f10] 'gud-gdb)(global-set-key (kbd "C-z&quo ...
- 向日期添加指定的时间间隔(mysql)
DATE_ADD( 原始日期, INTERVAL 要加的年数 YEAR) DATE_ADD( 原始日期, INTERVAL 要加的月份 MONTH) DATE_ADD( 原始日期, INTERVAL ...
- XAF-物料管理信息工作日志
前段时间已经开始了第一阶段验收了,客户方并未把重点放在业务流程上面,一直在调整一些界面问题.有点小纠结. 今天要调一下菜单位置. 没修改时,是这样的: 到了列表界面,会多一个全文检索出来. 后来,客户 ...
- Android测试入门学习
一,Android测试新人练习——安装及文件传输 [课前准备] Android测试环境搭建 1.下载并安装JDK: http://www.oracle.com/technetwork/java/jav ...
- spark重点知识
1 scala 2 spark rdd 3 sprak core 4 性能优化 5 spark sql 6 spark streaming 掌握程度-精通的理解:
- oracle数据库之组函数
组函数也叫聚合函数,用来对一组值进行运算,并且可以返回单个值 常见的组函数: (1)count(*),count(列名) 统计行数:找到所有不为 null 的数据来统计行数 (2)avg(列名) ...
- Javascript深入__proto__和prototype的区别和联系
有一个一个装逼的同事,写了一段代码 function a(){} a.__proto__.__proto__.__proto__ 然后问我,下面这个玩意a.__proto__.__proto__.__ ...
- jQuery 判断浏览器
jQuery 浏览器判断,jQuery提供了一个 jQuery.browser 方法 来判断浏览器 可用值: safari opera msie mozilla 例如:if($.brows ...