问题描述

BZOJ2820

LG2257


题解

求 \(\sum\limits_{i=1}^{n}{\sum\limits_{j=1}^{m}{[gcd(i,j)==p]}}\) ,其中 \(p\)为质数,\(n<m\) 。

考虑不要求 \(gcd(i,j)\) 为质数时的做法:

可以转化为

\[\sum\limits_{g=1}^{n}{g \times \sum\limits_{i=1}^{\lfloor \frac{n}{g} \rfloor}{\sum\limits_{j=1}^{\lfloor \frac{m}{g} \rfloor}{[gcd(i,j)==1]}}}
\]

根据狄利克雷卷积和莫比乌斯函数的性质,得

\[\sum\limits_{g=1}^{n}{g \times \sum\limits_{i=1}^{\lfloor \frac{n}{g} \rfloor}{\sum\limits_{j=1}^{\lfloor \frac{m}{g} \rfloor}{\sum\limits_{x|gcd(i,j)}{\mu(x)}}}}
\]

转化为枚举倍数,得

\[\sum\limits_{g=1}^{n}{g \times \sum\limits_{x=1}^{\lfloor \frac{n}{g} \rfloor}{\sum\limits_{i=1}^{\lfloor \frac{n}{gx} \rfloor}{\sum\limits_{j=1}^{\lfloor \frac{m}{gx} \rfloor}{1}}}}
\]

\[\sum\limits_{g=1}^{n}{g \times \sum\limits_{x=1}^{\lfloor \frac{n}{g} \rfloor}{\mu(x) \lfloor \frac{n}{gx} \rfloor \lfloor \frac{m}{gx} \rfloor}}
\]

接下来考虑 \(g\) 要是质数怎么办

构造函数 \(f(x)\),\(f(x)=\begin{cases}1&x \in \mathbb{P}\\0&x \notin \mathbb{P}\end{cases}\),其中 \(\mathbb{P}\) 为质数集合。

令 \(D=gx\) ,则要求的就是

\[\sum\limits_{D=1}^{n}{\lfloor \frac{n}{D} \rfloor \lfloor \frac{m}{D} \rfloor \times \sum\limits_{g|D}{f(g)\mu(\frac{D}{g})}}
\]

发现右边的 \(\sum\limits_{g|D}{f(g)\mu(\frac{D}{g})}\) 是狄利克雷卷积的形式。

设 \(h(x)=f*\mu\) ,则可以通过枚举倍数的时间,在 \(O(k \ln n)\) 的时间复杂度求出 \(h(x)\) ,其中 \(k\) 为 \([1,n]\) 中质数个数,约等于 \(\frac{n}{\ln n}\) ,于是约等于 \(O(n)\) 。

得到最终答案式子为

\[\sum\limits_{D=1}^{n}{h(D)\lfloor \frac{n}{D} \rfloor \lfloor \frac{m}{D} \rfloor}
\]


\(\mathrm{Code}\)

#include<bits/stdc++.h>
using namespace std; const int maxn=10000000; int p[maxn+7],pr[maxn+7],miu[maxn+7];
int h[maxn+7],T,tot; long long s[maxn+7]; void preprocess(void){
miu[1]=1;
for(int i=2;i<=maxn;i++){
if(!p[i]) p[i]=i,pr[++tot]=i,miu[i]=-1;
for(int j=1;j<=tot;j++){
if((long long)i*pr[j]>maxn||pr[j]>p[i]) break;
p[i*pr[j]]=pr[j];
if(i%pr[j]) miu[i*pr[j]]=-miu[i];
else miu[i*pr[j]]=0;
}
}
for(int i=1;i<=tot;i++){
for(int j=1;(long long)pr[i]*j<=maxn;j++){
h[pr[i]*j]+=miu[j];
}
}
for(int i=1;i<=maxn;i++) s[i]=s[i-1]+(long long)h[i];
} void Init(void){
scanf("%d",&T);
} long long calc(int x,int y){
if(x>y) swap(x,y);
long long res(0);
for( int l=1,r;l<=x;l=r+1){
r=min(x/(x/l),y/(y/l));
res+=(long long)(s[r]-s[l-1])*(long long)(x/l)*(y/l);
}
return res;
} void Work(void){
preprocess();
while(T--){
int x,y;
scanf("%d%d",&x,&y);
printf("%lld\n",calc(x,y));
}
} signed main(){
Init();
Work();
}

最新文章

  1. 如何区分Babel中的stage-0,stage-1,stage-2以及stage-3(一)
  2. 使用mxmlc在命令行编译.as代码
  3. BZOJ2080 : [Poi2010]Railway
  4. 意外作出了一个javascript的服务器,可以通过js调用并执行任何java(包括 所有java 内核基本库)及C#类库,并最终由 C# 执行你提交的javascript代码! 不敢藏私,特与大家分
  5. JavaScript 的数据类型 相关知识点
  6. $self $index $first $last parent() outerParent()
  7. HDU4289Control(最大流)
  8. varchar与nvarchar的区别
  9. Spire.XLS
  10. [CSS3] CSS Media Queries
  11. mysql数据库开始——增删改
  12. JMeter-MyEclipse编译运行问题(Could not read JMeter properties file)
  13. Flask 学习 六 大型程序结构
  14. Unity编辑器:清空控制台(Console)
  15. centOS7防火墙关闭失败问题
  16. Maven项目在更新过程停止,再更新无效--&gt;解决
  17. python接口自动化测试七:获取登录的Cookies,并关联到下一个请求
  18. Docker 微服务教程(搭建真正的网站)
  19. linux 批量替换
  20. 编程使用缓冲流读取试题文件,test6_5.txt 内容如下所示。 每次显示试题文件中的一道题目,读取到字符“*”时暂停读取, 等待用户从键盘输入答案。用户做完全部题目后,程序给出用户的得分。

热门文章

  1. Bayer图像处理 raw 数据解析
  2. table内容保存到Excel中
  3. kafka生产消息,streaming消费
  4. .NET Core的响应式框架,基于Ace Admin框架菜单导航,Bootstrap布局,fontAwesome图标,内嵌Iframe用EasyUI做数据绑定,动态配置列表,动态配置表单
  5. IPV6技术笔记(剖析IPv4toIPv6)
  6. 改进一条Group By
  7. Object类和异常
  8. DC8: Vulnhub Walkthrough
  9. css: hide or dispaly div
  10. Sqlite—数据库备份与恢复