[BZOI 3994] [SDOI2015]约数个数和

题面

设d(x)为x的约数个数,给定N、M,求\(\sum _{i=1}^n \sum_{i=1}^m d(i \times j)\)

T组询问,\(N,M,T \leq 50000\)

分析

首先有一个结论

\[d(nm)= \sum _{i |n} \sum _{j|m} [gcd(i,j)=1]
\]

这是因为nm的约数都可以表示为\(i \times \frac{m}{j}\)的形式,并且为了不重复算,要保证\(gcd(i,j)=1\)

因此,我们可以开始推式子

\[ans= \sum_{p=1}^n \sum_{q=1}^m \sum_{i|p} \sum _{j|q} [gcd(i,j)=1]
\]

注意到每对\((i,j)\)会对p,q中他们的倍数产生\(\lfloor \frac{n}{i} \rfloor \times \lfloor \frac{m}{j} \rfloor\) 的贡献

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

\[= \sum_{i=1}^n \sum_{j=1} ^m \varepsilon (gcd(i,j)) \lfloor \frac{n}{i} \rfloor \lfloor \frac{m}{j} \rfloor
\]

根据\(\varepsilon (n) = \sum_{d|n} \mu(d)\)

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

改变求和顺序,先枚举d,显然若\(d|gcd(i,j)\),则\(d|i,d|j\),

直接把i替换为d的倍数du,j替换为d的倍数dv(\(u,v \in N^+,du\leq n,dv \leq m\))

\[= \sum_{d=1}^{min(n,m)} \mu(d) \sum_{u=1}^{\lfloor n/d \rfloor} \sum_{v=1}^{\lfloor m/d \rfloor} \lfloor \frac{n}{du} \rfloor \lfloor \frac{m}{dv} \rfloor
\]

\[= \sum_{d=1}^{min(n,m)} \mu(d) \sum_{u=1}^{\lfloor n/d \rfloor} \sum_{v=1}^{\lfloor m/d \rfloor} \lfloor \frac{ \lfloor n/d \rfloor}{u} \rfloor \lfloor \frac{\lfloor m/d \rfloor}{v} \rfloor
\]

\[= \sum_{d=1}^{min(n,m)} \mu(d) \sum_{u=1}^{\lfloor n/d \rfloor} \lfloor \frac{ \lfloor n/d \rfloor}{u} \rfloor \sum_{v=1}^{\lfloor m/d \rfloor} \lfloor \frac{\lfloor m/d \rfloor}{v} \rfloor
\]

令\(g(n) = \sum _{d=1}^n \lfloor \frac{n}{d} \rfloor\)

\[=\sum_{d=1}^{min(n,m)} \mu(d) g(\lfloor \frac{n}{d} \rfloor) g(\lfloor \frac{m}{d} \rfloor)
\]

考虑如何快速求值。单个\(g(n)\)可以运用数论分块在\(O(\sqrt n)\)的时间内求出,总时间复杂度\(O(n \sqrt n)\). 然后线性筛出\(\mu\),以及\(\mu,g\)的前缀和

每次询问用数论分块的方法枚举d即可,总时间复杂度\(O(n \sqrt n +T \sqrt n)\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 50000
using namespace std;
typedef long long ll;
int t;
int n,m;
int cnt;
bool vis[maxn+5];
int prime[maxn+5];
int mu[maxn+5];
ll sum_mu[maxn+5];
int g[maxn+5];
void sieve(int n){
mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
prime[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0){
mu[i*prime[j]]=0;
break;
}else{
mu[i*prime[j]]=-mu[i];
}
}
}
for(int i=1;i<=n;i++) sum_mu[i]=sum_mu[i-1]+mu[i];
for(int i=1;i<=n;i++){
int l,r;
for(l=1;l<=i;l=r+1){
r=i/(i/l);
g[i]+=(ll)(r-l+1)*(i/l);
}
}
} ll calc(int n,int m){
int l,r;
if(n<m) swap(n,m);
ll ans=0;
for(l=1;l<=m;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=(sum_mu[r]-sum_mu[l-1])*g[n/l]*g[m/l];
}
return ans;
} int main(){
sieve(maxn);
scanf("%d",&t);
while(t--){
scanf("%d %d",&n,&m);
printf("%lld\n",calc(n,m));
}
}

[BZOI 3994] [SDOI2015]约数个数和(莫比乌斯反演+数论分块)的更多相关文章

  1. BZOJ 3994: [SDOI2015]约数个数和3994: [SDOI2015]约数个数和 莫比乌斯反演

    https://www.lydsy.com/JudgeOnline/problem.php?id=3994 https://blog.csdn.net/qq_36808030/article/deta ...

  2. BZOJ 3994: [SDOI2015]约数个数和 [莫比乌斯反演 转化]

    2015 题意:\(d(i)\)为i的约数个数,求\(\sum\limits_{i=1}^n \sum\limits_{j=1}^m d(ij)\) \(ij\)都爆int了.... 一开始想容斥一下 ...

  3. BZOJ.3994.[SDOI2015]约数个数和(莫比乌斯反演)

    题目链接 \(Description\) 求\[\sum_{i=1}^n\sum_{j=1}^md(ij)\] \(Solution\) 有结论:\[d(nm)=\sum_{i|d}\sum_{j|d ...

  4. P3327 [SDOI2015]约数个数和 莫比乌斯反演

    P3327 [SDOI2015]约数个数和 莫比乌斯反演 链接 luogu 思路 第一个式子我也不会,luogu有个证明,自己感悟吧. \[d(ij)=\sum\limits_{x|i}\sum\li ...

  5. 【BZOJ3994】[SDOI2015]约数个数和 莫比乌斯反演

    [BZOJ3994][SDOI2015]约数个数和 Description  设d(x)为x的约数个数,给定N.M,求   Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组 ...

  6. [SDOI2015]约数个数和 莫比乌斯反演

    ---题面--- 题解: 为什么SDOI这么喜欢莫比乌斯反演,,, 首先有一个结论$$d(ij) = \sum_{x|i}\sum_{y|j}[gcd(x, y) == 1]$$为什么呢?首先,可以看 ...

  7. luogu P3327 [SDOI2015]约数个数和 莫比乌斯反演

    题面 我的做法基于以下两个公式: \[[n=1]=\sum_{d|n}\mu(d)\] \[\sigma_0(i*j)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]\] 其中\(\ ...

  8. 洛谷P3327 [SDOI2015]约数个数和(莫比乌斯反演)

    题目描述 设d(x)为x的约数个数,给定N.M,求 \sum^N_{i=1}\sum^M_{j=1}d(ij)∑i=1N​∑j=1M​d(ij) 输入输出格式 输入格式: 输入文件包含多组测试数据.第 ...

  9. BZOJ3994: [SDOI2015]约数个数和(莫比乌斯反演)

    Description  设d(x)为x的约数个数,给定N.M,求     Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Out ...

随机推荐

  1. Jmeter性能测试请求超时:目前遇见有三种情况

    1.请求连接超时.连不上服务器.一般是因为线程太多 2.连接成功,但是读取超时.等不到服务器返回的数据,一般是这次请求查询的量很大,比如查了5度的顶点.(timeout小于server的最大等待时间) ...

  2. pycharm不支持svn,是需要svn命令行工具没有安装(for windows)

    1. 安装svn命令行工具 Subversion for Windows下载https://sourceforge.net/projects/win32svn/?source=typ_redirect ...

  3. Facebook再现丑闻,约100位应用程序开发人员偷看用户数据

    Facebook今天披露了另一起安全事件,承认大约100名应用程序开发人员可能不正确地访问了某些Facebook组中的用户数据,包括他们的姓名和个人资料图片. 在周二发布的博客文章中,Facebook ...

  4. kettle中使用mysql的tinyint 类型到slqserver的tinyint类型

    各个数据库之间的类型 定义还是有差别的 一下是我在工作中遇到的一个很奇葩的问题  mysql 中的 tinyint 类型 插入到sqlserver 的tinyint 类型 插入到 sqlserver的 ...

  5. Django框架架构总览

    Django框架架构总览 理解Django是如何运作的 条目创建于 2013-08-14     1464 views     服务器君一共花费 15.204 ms 进行了 4 次数据库查询,努力地为 ...

  6. JConsole和VisualVM远程访问JMX

    1.jvisualvm监控tomcat 修改tomcat的bin目录下的 catalina.sh文件,搜索JAVA_OPTS="",在引号中添加参数 JAVA_OPTS=" ...

  7. MySql的导入导出

    可以参看之前的博客:https://www.cnblogs.com/shijinglu2018/p/8672699.html 可以参看视频:https://i.cnblogs.com/EditPost ...

  8. 适用于填空题出题 的随机算法 PHP

    <?php #寻找一个满足给定空数和题数要求的随机方案,事先需统计出每题空格数情况队列$m_blk,以及这些题分别有多少个$m_que. #以下算法将找到一个随机方案,若未找到将返回假值,如果不 ...

  9. 洛谷P1310 表达式的值——题解

    题目传送 题的难点:1.有运算优先级,不好判断.2.有破坏整体和谐性的讨厌的括号.3.不知道哪里要填数.4.要求方案数很大,搜索不会做呐. 发现难点1和2都是中缀表达式的缺点.转成后缀表达式后难点1. ...

  10. (转)JNI参数传递|Surface && sign签名对应

    http://blog.csdn.net/stefzeus/article/details/6622011 char* Get_Surface(JNIEnv *env, jclass cls, job ...