点此看题面

大致题意: 让你求出\(\sum_{i=1}^n\sum_{j=1}^n\mu(gcd(i,j))\)。

莫比乌斯反演

这种题目,一看就是莫比乌斯反演啊!(连莫比乌斯函数都有)

关于莫比乌斯反演,详见这篇博客:初学莫比乌斯反演

推式子

下面让我们来推式子。

首先,我们采用解决这种问题的常用套路,来枚举\(gcd\),就能得到这样一个式子:

\[\sum_{d=1}^n\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}[gcd(i,j)==1]\mu(d)
\]

将\(\mu(d)\)提前,可得:

\[\sum_{d=1}^n\mu(d)\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^{\lfloor\frac nd\rfloor}[gcd(i,j)==1]
\]

针对后半部分的式子,考虑当\(i>j\)时,其实等价于\(i\)和\(j\)交换后的答案。

这样一来,我们就可以想到把\(j\)的上限改为\(i\)。

注意\(i=j\)时,若\(i=j=1\),则\(gcd(i,j)=1\),其余情况\(gcd(i,j)\)必定不为\(1\),因此要单独处理这种情况,将结果减\(1\)。

于是就得到这样一个式子:

\[\sum_{d=1}^n\mu(d)(2\sum_{i=1}^{\lfloor\frac nd\rfloor}\sum_{j=1}^i[gcd(i,j)==1]-1)
\]

根据\(\phi\)的定义可得,\(\sum_{j=1}^i[gcd(i,j)==1]\)其实就等于\(\phi(i)\),因此可得:

\[\sum_{d=1}^n\mu(d)(2\sum_{i=1}^{\lfloor\frac nd\rfloor}\phi(i)-1)
\]

这时的式子就已经足够简单了。

求答案

考虑如何求答案。

由于值域较大,因此我们必须使用杜教筛来筛\(\mu\)和\(\phi\)这两个函数。

由于后半部分的上限\(\lfloor\frac nd\rfloor\),因此我们必须使用除法分块来对这个式子进行优化。

这样就可以了。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define X 998244353
#define LL long long
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
#define Dec(x,y) ((x-=(y))<0&&(x+=X))
#define XSum(x,y) ((x)+(y)>=X?(x)+(y)-X:(x)+(y))
using namespace std;
LL n;
class DuSiever//杜教筛
{
private:
static const int SZ=10000000;int Pcnt,P[SZ+5],phi[SZ+5],mu[SZ+5],Sphi[SZ+5],Smu[SZ+5];
map<LL,int> Mphi,Mmu;
public:
I DuSiever()//初始化
{
RI i,j;for(phi[1]=mu[1]=1,i=2;i<=SZ;++i)
for(!P[i]&&(phi[P[++Pcnt]=i]=i-1,mu[i]=-1),j=1;j<=Pcnt&&1LL*i*P[j]<=SZ;++j)
if(P[i*P[j]]=1,i%P[j]) phi[i*P[j]]=phi[i]*(P[j]-1),mu[i*P[j]]=-mu[i];else {phi[i*P[j]]=phi[i]*P[j];break;}
for(i=1;i<=SZ;++i) Sphi[i]=XSum(Sphi[i-1],phi[i]),Smu[i]=XSum(XSum(Smu[i-1],mu[i]),X);
}
I int Gphi(Con LL& x)//筛phi
{
if(x<=SZ) return Sphi[x];if(Mphi.count(x)) return Mphi[x];
RI res=1LL*x%X*(x+1)%X*(X+1>>1)%X;Reg LL l,r;//千万注意此处x直接乘x+1会爆long long,因此要先取模(为此调了一个小时)
for(l=2;l<=x;l=r+1) r=x/(x/l),Dec(res,1LL*(r-l+1)*Gphi(x/l)%X);
return Mphi[x]=res;
}
I int Gmu(Con LL& x)//筛mu
{
if(x<=SZ) return Smu[x];if(Mmu.count(x)) return Mmu[x];
RI res=1;Reg LL l,r;
for(l=2;l<=x;l=r+1) r=x/(x/l),Dec(res,1LL*(r-l+1)*Gmu(x/l)%X);
return Mmu[x]=res;
}
}D;
int main()
{
RI ans=0;Reg LL l,r;for(scanf("%lld",&n),l=1;l<=n;l=r+1)//除法分块
r=n/(n/l),Inc(ans,1LL*(D.Gmu(r)-D.Gmu(l-1)+X)%X*((D.Gphi(n/l)<<1)-1)%X);
return printf("%d",ans),0;//输出答案
}

最新文章

  1. CentOS 搭建openVPN
  2. 扩展progress_timer的计时精度
  3. 关于Java项目打包
  4. [转载][翻译] 利用JSF、SpringFramework和Hibernate构建Web应用的实例讲述
  5. redhat RHEL 5.5 下载地址
  6. oracle数据库数据导出和导入
  7. (转)直接拿来用!最火的iOS开源项目(一)
  8. WPF DataGrid_SelectChanged获取单元内容
  9. Swift的74标准功能
  10. Mahout canopy聚类
  11. MySQL中的外键约束
  12. JS截取URL地址参数
  13. UITableViewCell图片视差效果
  14. SQL SERVER2008 DBX Error: Driver could not be properly initialized
  15. AS3 - 数组元素乱序方法以及效率比较
  16. 鼠标键盘失灵对策(Windows8.1)
  17. 关于初次使用Linux的一些小经验
  18. 为什么全部width:100%浏览器边缘存在留白?
  19. 玩转kafka
  20. 解决存储过程中拼接的SQL字符串超长导致sql语句被截取的问题

热门文章

  1. 2.1 Rust概念
  2. c++ 封装线程库 2
  3. java多线程(四)
  4. java 静态变量生命周期(类生命周期)(转)
  5. chrome 修改请求头的小工具
  6. 2019.03.22 读书笔记 var object dynamic
  7. Kudu的Using Apache Kudu with Apache Impala(官网推荐的步骤)
  8. 断路器hystrix
  9. 将应用图标添加到ubuntu dash中
  10. ZK典型应用场景