【数论】积性函数、莫比乌斯反演、狄利克雷卷积
莫比乌斯函数应该还是比较广为人知的吧
函数,它的定义如下:
(1)若,那么
(2)若,均为互异素数,那么
(3)其它情况下
对于函数,它有如下的常见性质:
(1)对任意正整数有
(2)对任意正整数有
反演一般有两种形式
莫比乌斯反演的一般描述为:
另一种做题非常常用的函数:
我的目标就是先清理那些收藏夹的题目
题目描述
神犇YY虐完数论后给傻×kAc出了一题
给定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)为质数的(x, y)有多少对
kAc这种傻×必然不会了,于是向你来请教……
多组输入
输入输出格式
输入格式:第一行一个整数T 表述数据组数
接下来T行,每行两个正整数,表示N, M
输出格式:T行,每行一个整数表示第i组数据的结果
输入输出样例
说明
T = 10000
N, M <= 10000000
题目要求的就是∑ni=1∑mj=1[gcd(x,y)=prim]
化简出来Ans=∑T=1min(n,m)⌊nT⌋⌊mT⌋(∑t|T,t∈primeμ(⌊Tt⌋))
就是整除分块啦
#include<bits/stdc++.h> #define N 10000005 bool vis[N]; long long sum[N]; int prim[N]; int mu[N],g[N]; int cnt; void get_mu() { mu[1]=1; for(int i=2; i<N; i++) { if(!vis[i]) mu[i]=-1,prim[++cnt]=i; for(int j=1; j<=cnt&&prim[j]*i<N; j++) { vis[i*prim[j]]=1; if(i%prim[j]==0)break; else mu[prim[j]*i]=-mu[i]; } } for(int j=1; j<=cnt; j++)for(int i=1; i*prim[j]<N; i++)g[i*prim[j]]+=mu[i]; for(int i=1; i<N; i++)sum[i]=sum[i-1]+g[i]; } int n,m; int main() { get_mu(); int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); if(n>m)std::swap(n,m); long long ans=0; for(int l=1,r; l<=n; l=r+1) r=std::min(n/(n/l),m/(m/l)),ans+=1ll*(n/l)*(m/l)*(sum[r]-sum[l-1]); printf("%lld ",ans); } return 0; }
luoguP3327 [SDOI2015]约数个数和
题目描述
设d(x)为x的约数个数,给定N、M,求 sum^N_{i=1}sum^M_{j=1}d(ij)∑i=1N∑j=1Md(ij)
输入输出格式
输入格式:
输入文件包含多组测试数据。第一行,一个整数T,表示测试数据的组数。接下来的T行,每行两个整数N、M。
输出格式:
T行,每行一个整数,表示你所求的答案。
输入输出样例
说明
1<=N, M<=50000
1<=T<=50000
这个函数比较套路