2017.3.19 约数个数和 失败总结
来源:互联网 发布:网络研修的收获 编辑:程序博客网 时间:2024/06/04 23:11
这个题一眼上去应该不是很难,但除了求约数个数有个分解质因数的技巧之外就不会什么了;;
本来想着预处理50000以内的约数个数和之后求个前缀和直接乘、、、可见多么蠢、、搞了2h后弃疗了
结果题解是 要算gcd (。_。)
还有莫比乌斯反演、、、 …(⊙_⊙;)…
好吧,先借机学一下莫比乌斯反演 、、
其实这道题几乎就是为莫比乌斯而生的(板子题)
似乎是函数的反函数、、
所以叫反演、、 (*゜ー゜*)
而这个μ函数就是传说中的的莫比乌斯函数;
要注意是F(n/d)
那这个要怎么用?
那此题来说,首先要证明这个式子:
为什么会和gcd有关?
若i和j互质,那么i*j就是对于d(mn)唯一的约数
如果不互质,那么i和j还能再拆出几个数,作为约数
如 i=4 j=6,n=8,j=12;;
i=2*2 j=2*3
那么 i*j=2*2*2*3
可以写出互质的8 * 3
在循环到i=8,j=3时会被算进去、
而这些拆出的数一定可以对答案贡献1
所以用了bool;;
然后原式相当于求1~n、1~m的和:
根据 sigma交换律 和 可以处理处的某个积性函数μ可以得出莫比乌斯反演,:
(就是套公式, 【gcd(a,b)==1】= Σ(d|i,d|j)μ(d) )
注意μ是根据d能否整除i、d能否整除j 对d的一个函数,返回数值
有人可能要问gcd的判断和 i、j、d的整除关系得到的函数有什么关系?
注意多了一个Σ:也就是说它是先用前面四坨Σ枚举了1~n、 1~m所有可能的约数、、而这最后一个Σ则是枚举约数的约数、、(当然,默认N<M)
若d既整除了i,又整除了j,则i和j不互质,它有公因数d、、、
然后就不会了
我们注意到会有很多重复,重复的个数为 下取整(N/i) 所以可以用乘法优化加法,干掉两个Σ、、
这是反演的一步通用优化
再从d(约数)的角度交换一下位置:
对于每个d都要乘每种可能的i、j搭配,但对于n、m只会出现n/d、m/d次,每次搭配又会产生n/(i*d)、 m/(j*d)个重复
所以都可以乘起来再加
把最右边两项的d写到分子:
我们可以发现有两个不相关的项,可以独立处理:
而且这两个函数计算方式一毛一样,只是定义域值域不一样所以:
就可以化为:
分别处理f函数,再用线筛求出μ函数,就可以做了;;;
码:
#include<iostream>#include<cstdio>using namespace std;#define ll long longint mu[50001];ll f[50001],ans; int i,j,n,tot,su[50001],k,t,m;bool vis[50001];void eular(){mu[1]=1;for(int i=2;i<=50000;i++){if(!vis[i]){su[++tot]=i;mu[i]=-1;//质数统一为 -1 }for(j=1;i*su[j]<50000&&j<=tot;j++){ vis[i*su[j]]=1; if(i%su[j]) { mu[i*su[j]]=-mu[i];//合数如果没有>2的次方的质数就看元素个数(取反,即为(-1)^n) }else { mu[i*su[j]]=0;//合数如果是p^n形式,mu就是0 break; }}} for (i=2; i<=50000; i++) mu[i]+=mu[i-1]; //处理前缀和(因为题目有Σ) for (i=1; i<=50000; i++) //计算f for (j=1; j<=i; j=k+1){ k=i/(i/j); //可能有点mengbi,k存的是最大的i/j,同 余数之和sum一题 f[i]+=(ll)(k-j+1)*(i/j); //用乘法加速连加 } }int main(){ scanf("%d",&t);eular();while(t--){ scanf("%d%d",&n,&m);ans=0; for (i=1; i<=m && i<=n; i=j+1){//枚举p,计算贡献 j=min(m/(m/i),n/(n/i)); //同余数之和sum的计算方式 ans+=f[m/i]*f[n/i]*(mu[j]-mu[i-1]);//用公式+前缀和统计答案 } if(t)printf("%lld\n",ans); else printf("%lld",ans);}}
莫比乌斯反演就是一个渠道,可以通过这个渠道对看似没有办法化简的式子转化为若干子函数,这样复杂度就会降低、
但式子的转化极其灵活,必须确保每一步正确性,
可以说,能用莫比乌斯反演的题都需要极强的数学敏感度和缜密的推理
当然,暴力性价比高、
附一张反演函数计算法则:
- 2017.3.19 约数个数和 失败总结
- 约数个数及约数和
- [bzoj3994]约数个数和
- 约数个数定理 和 约数和定理
- 约数个数定理and约数和定理
- 线性筛 [约数个数/约数和]
- 【SDOI2015】【BZOJ3994】约数个数和
- [BZOJ3994][SDOI2015]约数个数和
- BZOJ3994: [SDOI2015]约数个数和
- [bzoj3994][SDOI2015]约数个数和
- bzoj3994【SDOI2005】约数个数和
- 【BZOJ3994】【SDOI2015】约数个数和
- 【bzoj3994】[SDOI2015]约数个数和
- 3994: [SDOI2015]约数个数和
- bzoj3994: [SDOI2015]约数个数和
- bzoj3994[SDOI2015]约数个数和
- BZOJ3994: [SDOI2015]约数个数和
- bzoj3994 [SDOI2015]约数个数和
- 漫步数学分析番外六(上)
- mac os系统下clion和xcode调用freopen函数
- 算法训练 瓷砖铺放
- hdu3671 Boonie and Clyde Tarjan求割点
- 第一届CCF考试题解(4)
- 2017.3.19 约数个数和 失败总结
- Metadata Service 架构详解
- C#基础运算符
- pandas.DataFrame.to_csv
- B1021. 个位数统计 (15)
- OpenCv-python之图像的缩放和旋转
- easyUi中portal组件的使用
- MyAppliction
- C#开发微信公众平台-就这么简单(附Demo)