所以我刚学反演还没学反演就要做这么一道神仙题……

首先大于n不好求,补集转化。

$ans=n*n-\sum \limits _{i=1}^{n} \sum \limits _{j=1}^{n} \left [  lcm(i,j)\leqslant n\right ] $

那么我们要求:

$\sum \limits _{i=1}^{n} \sum \limits _{j=1}^{n} \left [  \frac{i*j}{gcd(i,j) } \leqslant n \right ]$

枚举d=gcd(i,j),

原式=$\sum \limits _{d=1}^{n} \sum \limits _{i=1}^{n} \sum \limits _{j=1}^{n} \left [ i*j*d\leqslant n ,gcd(i,j)=1 \right ]$

=$\sum \limits _{d=1}^{n} \sum \limits _{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \sum \limits _{j=1}^{\left \lfloor \frac{n}{d*i} \right \rfloor} \left [ gcd(i,j)=1 \right ]$

根据莫比乌斯函数的性质:$\sum \limits _{d\mid n}u(d) =\left [ n=1 \right ]$

于是原式=$\sum \limits _{d=1}^{n} \sum \limits _{i=1}^{n} \sum \limits _{j=1}^{n} \sum \limits _{g\mid gcd(i,j)} u(g)$

所以就要反演了?其实就是交换求和的顺序。

个人这步稍难理解(因为我没学过反演),将g提前后相当于求u(g)出现的次数,那么修改g的定义,令${i}'=\frac{i}{g},{j}'=\frac{j}{g}$.

原式=$\sum \limits _{d=1}^{n} \sum \limits _{g=1} u(g) \sum \limits _{{i}'=1}^{\left \lfloor \frac{n}{d*g} \right \rfloor} \sum \limits _{{j}'=1}^{\left \lfloor \frac{n}{d*i*g} \right \rfloor} 1$

将g提前,原式=$\sum \limits _{g=1}^{\sqrt{n}}u(g) \sum \limits _{{i}'=1} \sum \limits _{{j}'=1} \sum \limits _{d=1} \left [ {i}'*{j}'*d\leqslant \frac{n}{g*g} \right ]$

到此式子就推完了,可是看起来还是不是很可做……但是可以发现g是根号n范围内的,u线筛即可,同时枚举g。

不妨设${i}'\leqslant {j}'\leq d$,那么设$m=\frac{n}{g*g}$可以以$O\left ( m^{\frac{1}{3}} \right )$的复杂度枚举i,以$\sqrt{\frac{m}{i}}$的复杂度枚举j,O1算出d的个数,之后乘$A_3^3$。

但是要考虑算重的情况,手动讨论一下就行了。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define int LL
#define LL long long
using namespace std;
const int mod=1e9+;
LL n;
bool isprime[];
int prime[],cnt,mu[];
void shai(int n)
{
mu[]=;
for(int i=;i<=n;i++)isprime[i]=;
for(int i=;i<=n;i++)
{
if(isprime[i])mu[i]=-,prime[++cnt]=i;
for(int j=;j<=cnt&&prime[j]*i<=n;j++)
{
isprime[prime[j]*i]=;
if(i%prime[j]==)break;
else mu[i*prime[j]]=-mu[i];
}
}
}
signed main()
{
cin>>n;int maxn=sqrt(n);shai(maxn+);
LL ans=;
for(int i=;i<=maxn;i++)
{
LL res=;
int m=n/(i*i);
for(int a=;a*a*a<=m;a++)
{
int maxb=sqrt((1.0*m)/a);
for(int b=a;b<=maxb;b++)
if(m/(a*b)>=b)
{
if(a==b)res=(res+(m/(a*b)-b)*+)%mod;
else res=(res+(m/(a*b)-b)*+)%mod;
}
}
ans=(ans+mu[i]*res%mod)%mod;
}
printf("%lld\n",(n%mod*(n%mod)%mod-ans%mod+mod)%mod);
}

最新文章

  1. Maven命令行使用:mvn clean compile(编译)
  2. go语言 安装版 Windows7安装截图
  3. Cadence Allegro元件封装制作流程
  4. jdk 1.8 Executors
  5. SAP的物料归档
  6. 三、XML编程(CRUD)
  7. suibi11172
  8. tengine+lua的安装步骤
  9. CentOS目录结构详解
  10. python os语法
  11. SPOJ 1811 LCS [后缀自动机]
  12. PHP_DOC php文档结构及注解浏览
  13. (Prim算法)codeVs 1078 最小生成树
  14. 使用多线程提高Rest服务性能
  15. PythonStudy——高级语言 High-level programming language
  16. jenkins管理
  17. 语义SLAM的数据关联和语义定位(四)多目标测量概率模型
  18. 实例Python处理XML文件的方法
  19. 在EO中获取某字段基于表的列名
  20. 转载-java基础学习汇总

热门文章

  1. HYSBZ 1015/BZOJ1015 星球大战starwar
  2. Visual Studio 2019 正式发布
  3. LintCode_415 有效回文串
  4. Codeforces 220B
  5. Amazon EBS的功能更新
  6. 学习JDK1.8集合源码之--ArrayDeque
  7. python基础--数据类型的常用方法2
  8. Vue. 之 Element table 单元格内容隐藏
  9. 【流水调度问题】【邻项交换对比】【Johnson法则】洛谷P1080国王游戏/P1248加工生产调度/P2123皇后游戏/P1541爬山
  10. Swift 和 Objective-C 混编后对ipa包大小的影响