[SDOI2015][bzoj3994] 约数个数和 [莫比乌斯反演]
题面:
思路:
首先,我们需要证明一个结论:d(i*j)等于sigma(gcd(x,y)==1),其中x为i的约数,y为j的约数
对于nm的每一个质因子pi分别考虑,设n = pi^ai + n',m = pi^bi + m'
那么显然质因子pi对d(nm)的贡献为(ai+bi+1)
同理,考虑右边的式子,我们发现质数pi对右侧做的贡献仍然是(ai+bi+1),即如下的(x,y)
(pi^ai,1) (pi^(ai-1),1) ..... (1,1) .....(1,pi^(bi-1)) (1,pi^bi)
因此左右两式相同
因此原待求表达式化为如下形式:
由莫比乌斯函数第二情况得:上式可化为
其中g(i)表示前半个式子中的那段东西,相当于d(i)的前缀和
于是O(Tsqrt(min(n,m))轻松解决
顺便说一句,求约数个数也有线性的方法
记录c[i]表示i的最小的质因子的次数
每次更新这个,然后同时用c[i]+1更新d[i*pri[j]]即可
Code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
inline ll read(){
ll re=,flag=;char ch=getchar();
while(ch>''||ch<''){
if(ch=='-') flag=-;
ch=getchar();
}
while(ch>=''&&ch<='') re=(re<<)+(re<<)+ch-'',ch=getchar();
return re*flag;
}
ll mu[],pri[],c[],d[],cnt;bool vis[];
void init(ll n){
mu[]=d[]=c[]=;ll i,j,k;
for(i=;i<=n;i++){
if(!vis[i]){
pri[++cnt]=i;mu[i]=-;c[i]=;d[i]=;
}
for(j=;(j<=cnt)&&(i*pri[j]<=n);j++){
k=i*pri[j];vis[k]=;
if(i%pri[j]==){
d[k]=d[i]/(c[i]+)*(c[i]+);
c[k]=c[i]+;break;
}
mu[k]=-mu[i];
d[k]=d[i]*d[pri[j]];c[k]=;
}
}
for(i=;i<=n;i++) mu[i]+=mu[i-];
for(i=;i<=n;i++) d[i]+=d[i-];
}
ll n,m;
int main(){
ll i,j,T=read(),ans;init();
while(T--){
n=read();m=read();ans=;
if(n>m) swap(m,n);
for(i=;i<=n;i=j+){
j=min(n/(n/i),m/(m/i));
ans+=(mu[j]-mu[i-])*d[n/i]*d[m/i];
}
printf("%lld\n",ans);
}
}
[SDOI2015][bzoj3994] 约数个数和 [莫比乌斯反演]的更多相关文章
- P3327 [SDOI2015]约数个数和 莫比乌斯反演
P3327 [SDOI2015]约数个数和 莫比乌斯反演 链接 luogu 思路 第一个式子我也不会,luogu有个证明,自己感悟吧. \[d(ij)=\sum\limits_{x|i}\sum\li ...
- 【BZOJ3994】[SDOI2015]约数个数和 莫比乌斯反演
[BZOJ3994][SDOI2015]约数个数和 Description 设d(x)为x的约数个数,给定N.M,求 Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组 ...
- BZOJ3994: [SDOI2015]约数个数和(莫比乌斯反演)
Description 设d(x)为x的约数个数,给定N.M,求 Input 输入文件包含多组测试数据. 第一行,一个整数T,表示测试数据的组数. 接下来的T行,每行两个整数N.M. Out ...
- [SDOI2015][bzoj 3994][Luogu P3327] 约数个数和 (莫比乌斯反演)
题目描述 设d(x)d(x)d(x)为xxx的约数个数,给定NNN.MMM,求 ∑i=1N∑j=1Md(ij)\sum^{N}_{i=1}\sum^{M}_{j=1} d(ij)i=1∑Nj=1∑M ...
- [SDOI2015]约数个数和 莫比乌斯反演
---题面--- 题解: 为什么SDOI这么喜欢莫比乌斯反演,,, 首先有一个结论$$d(ij) = \sum_{x|i}\sum_{y|j}[gcd(x, y) == 1]$$为什么呢?首先,可以看 ...
- luogu P3327 [SDOI2015]约数个数和 莫比乌斯反演
题面 我的做法基于以下两个公式: \[[n=1]=\sum_{d|n}\mu(d)\] \[\sigma_0(i*j)=\sum_{x|i}\sum_{y|j}[gcd(x,y)=1]\] 其中\(\ ...
- [BZOI 3994] [SDOI2015]约数个数和(莫比乌斯反演+数论分块)
[BZOI 3994] [SDOI2015]约数个数和 题面 设d(x)为x的约数个数,给定N.M,求\(\sum _{i=1}^n \sum_{i=1}^m d(i \times j)\) T组询问 ...
- BZOJ 3994: [SDOI2015]约数个数和 [莫比乌斯反演 转化]
2015 题意:\(d(i)\)为i的约数个数,求\(\sum\limits_{i=1}^n \sum\limits_{j=1}^m d(ij)\) \(ij\)都爆int了.... 一开始想容斥一下 ...
- BZOJ 3994: [SDOI2015]约数个数和3994: [SDOI2015]约数个数和 莫比乌斯反演
https://www.lydsy.com/JudgeOnline/problem.php?id=3994 https://blog.csdn.net/qq_36808030/article/deta ...
随机推荐
- bootstrap3 文档随看
唉 昨天看的是2,早知道就只可以看3啦,虽然整体不变,但是小改小闹的还是很多啦.产品上线是需要升级的,但是像这么改会很烦哎,有些样式名字修改,用法修改,功能修改,那让用惯了2的人还得把之前记忆清除了然 ...
- js表单序列化时,非空判断
在项目中,对于数据的传输一般需要非空的判断,而数据字段较多时一般直接将表单序列化,此时如何判断非空,如下 因为将表单序列化时,数据格式为 trainKind=1&trainKindCode=1 ...
- C# checked运算符
一.C# checked运算符 checked运算符用于对整型算术运算和显式转换启用溢出检查. 默认情况下,表达式产生的值如果超出了目标类型的范围,将会产生两种情况: ?常数表达式将导致编译时错误. ...
- C# 运用StreamReader类和StreamWriter类实现文件的读写操作
对文件的读写操作应该是最重要的文件操作,System.IO命名空间为我们提供了诸多文件读写操作类,在这里我要向大家介绍最常用也是最基本的StreamReader类和StreamWriter类.从这两个 ...
- 使用git stash命令保存和恢复进度
使用git stash命令保存和恢复进度 git stash 保存当前工作进度,会把暂存区和工作区的改动保存起来.执行完这个命令后,在运行git status命令,就会发现当前是一个干净的工作区,没有 ...
- C++性能优化笔记
最近着手去优化项目中一个模块的性能.该模块是用C++实现,对大量文本数据进行处理. 一开始时,没什么思路,因为不知道性能瓶颈在哪里.于是借助perf工具来对程序进行分析,找出程序的性能都消耗在哪里了. ...
- python2与python3下的base64模块
Python2的编解码 python2中程序数据类型默认为ASCII,所以需要先将数据解码(decode)成为Unicode类型,然后再编码(encode)成为想要转换的数据类型(gbk,utf-8, ...
- 进入docker容器并执行命令的的3中方法
进入docker容器并执行命令的的3中方法 docker exec nsenter docker attach "container" 建议使用nsenter, exec有 ...
- 一个简单的linux下设置定时执行shell脚本的示例
很多时候我们有希望服务器定时去运行一个脚本来触发一个操作,比如说定时去备份服务器数据.数据库数据等 不适合人工经常做的一些操作这里简单说下 shell Shell俗称壳,类似于DOS下的command ...
- B1023 组个最小数 (20分)
B1023 组个最小数 (20分) 给定数字 0-9各若干个.你可以以任意顺序排列这些数字,但必须全部使用.目标是使得最后得到的数尽可能小(注意 0 不能做首位).例如:给定两个 0,两个 1,三个 ...