P2257 YY的GCD

解题思路

果然数论的题是真心不好搞。

第一个莫比乌斯反演的题,好好推一下式子吧。。(借鉴了blog

我们要求的答案就是\(Ans=\sum\limits_{i=1}^{n}\sum\limits _{j=1}^{m}[\gcd(x,y)=prim]\)

这算是一类题了,大概套路如下:

  • \(f[d]\) 表示 \(\gcd(i,j)\) 所有的方案数。

    即:\(f(d)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[gcd(i,j)=d]\)

  • \(F(n)\) 为 \(\gcd(i,j)=n\) 和 \(n\) 的倍数的个数

    即:\(F(n)=\sum\limits_{n|d}f(d)=\lfloor\frac{N}{n}\rfloor\lfloor\frac{M}{n}\rfloor\)

    也就是N中为n的倍数的数目与M中为n的倍数的数目的乘积就是所求的 F(n) 了。

  • 根据以上的定义,莫比乌斯反演不难得出:

    \(f(n)=\sum\limits_{n|d}\mu(\lfloor\frac{d}{n}\rfloor)F(d)\)

    接下来就是化简式子

\(Ans=\sum\limits_{p\in prim}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[gcd(i,j)=p]\)

将\(f(p)\)带入上面式子:

\(Ans=\sum\limits_{p\in prim}f(p)\)

再用上面的式子3莫比乌斯反演一下:

\(Ans=\sum\limits_{p\in prim}\sum\limits_{p|d}\mu(\lfloor\frac{d}{p}\rfloor)F(d)\)

将之前给出的\(F(n)\)表达式带入,再更改一下循环顺序:

\(Ans=\sum\limits_{T=1}^{min(n,m)}\sum\limits_{t|T,t\in prime}\mu(\lfloor\frac{T}{t}\rfloor)\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\)

\(Ans=\sum\limits_{T=1}^{min(n,m)}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor(\sum\limits_{t|T,t\in prime}\mu(\lfloor\frac{T}{t}\rfloor))\)

最后,数论分块一下求一个前缀和就好了。

数论分块:

对于任意一个\(i(i \le n)\),我们需要找到一个最大的 \(j(i \le j \le n )\),使得

此时

  • 注意:只有ans开 long long就好了,都开的话会TLE

code

#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=1e7+10;
int T,n,m,ans;
int cnt,f[N],sum[N],mu[N],pri[N];
bool vis[N];
void get_Mobius()
{
mu[1]=1;
for(int i=2;i<N;i++)
{
if(!vis[i])
{
mu[i]=-1;
pri[++cnt]=i;
}
for(int j=1;j<=cnt&&pri[j]*i<N;j++)
{
vis[i*pri[j]]=true;
if(i%pri[j]==0)
break;
else
mu[pri[j]*i]=-mu[i];
}
}
for(int i=1;i<=cnt;i++)
for(int j=1;j*pri[i]<N;j++)
f[j*pri[i]]+=mu[j];
for(int i=1;i<N;i++)
sum[i]=sum[i-1]+f[i];
}
//#undef int
int main()
{
// #define int register long long
#define ll long long
scanf("%d",&T);
get_Mobius();
while(T--)
{
scanf("%d%d",&n,&m);
ll ans=0;
if(n>m)
swap(n,m);
for(int l=1,r;l<=n;l=r+1)
{
r=min(n/(n/l),m/(m/l));
ans+=1ll*(n/l)*(m/l)*(sum[r]-sum[l-1]);
}
printf("%lld\n",ans);
}
return 0;
}

最新文章

  1. DB2 SQL 日期函数
  2. 可滑动的ExpandableListView
  3. JS文件放在头还是尾
  4. javascript/jquery键盘事件介绍
  5. 电脑右键新建文本文档(txt)消失的解决办法
  6. 一个类似repo的小程序
  7. [cc150] 硬币问题
  8. PHP Sessions子系统会话固定漏洞
  9. Java学习----Java数据类型
  10. PHPStorm调试PHP代码~实际操作+mark~~
  11. Java架构师学习路线
  12. 阿里云API网关(18)请求报文和响应报文
  13. mktemp 命令
  14. MyBatis源码解析(十二)——binding绑定模块之MapperRegisty
  15. Linux 文件夹相关常用命令
  16. 安卓开发_浅谈Notification(通知栏)
  17. xdoj新生现场赛1269——带有限制条件的bfs 寻找最短路径
  18. hdu 1556 Color the ball(树状数组)
  19. Java从零开始学十(Arrays类对数组的常用方法)
  20. #include &lt;ntifs.h&gt;出现PEPROCESS redefinition问题处理

热门文章

  1. Mybatis学习之自定义持久层框架(五) 自定义持久层框架:封装CRUD操作
  2. python爬虫——《英雄联盟》英雄及皮肤图片
  3. 如何用Vim搭建IDE?
  4. 技能Get&#183;BOM头是什么?
  5. [Linux] Shell 脚本实例(超实用)
  6. [刷题] 70 Climbing Stairs
  7. 【转载】CentOS 7自动以root身份登录gnome桌面 操作系统开机后自动登录到桌面 跳过GDM
  8. python从hello world开始(3)
  9. Linux 操作系统(四)用户组管理&amp;进程管理&amp;任务调度
  10. 高通 QC协议 谷歌 PD协议