数论

暂时鸽了

归不到类,说实话不知道从哪里开始。

一些记号

积性函数

没啥好说。如果一个定义在 N+ 集合上的函数 f 满足对于任意一对互质的正整数 p,q 都有 f(pq)=f(p)f(q),则称 f 为积性函数。若是对于任意正整数 p,q 都有 f(pq)=f(p)f(q) 则称 f 为完全积性函数。

性质:若 f,g 是积性函数,则 h=fg 也是积性函数。

狄利克雷卷积&生成函数

定义

定义为在数论函数之间的一种二元运算,是数论函数的重要运算,数论函数的许多性质都是通过这个运算挖掘出来的。对于两个数论函数 f(x),g(x),他们的狄利克雷卷积得到的结果 h(x) 定义为:h(x)=d|xf(d)g(xd)=ab=xf(a)g(b),简记为 h=fg

同时我们有狄利克雷生成函数(DGF)。对于一个无穷序列 f1,f2,,定义其狄利克雷生成函数为 F~(x)=i1fiix

对于两个序列 f,g,其狄利克雷生成函数之积,对应的是两者的狄利克雷卷积序列的狄利克雷生成函数:F(x)G(x)=ijfigi(ij)x=i1ixd|ifdg1d

性质

满足一般的交换律、结合律、分配律,并且 f=g 的充要条件是 fh=gh,其中数论函数 h(1)0

单位元:令单位函数 ε 是狄利克雷卷积运算中的单位元,及对于任何数论函数 f 都有 fε=f

逆元:对于任何一个满足 f(x)0 的数论函数,如果有 g(x) 满足 fg=ε,则称 g(x)f(x) 的逆元,逆元是唯一的。g(x)=ε(x)d|x,d1f(d)g(xd)f(1)

两个结论:两个积性函数的 Dirichlet 卷积也是积性函数一个积性函数的逆元也是积性函数证明不想证。

整除分块

为什么我的中括号打出来就是上取整(
引入:求 inni。我们通过观察可以得到 n/i 只有大约 2n 种结果,我们就可以把每一种相同的结果都合并到一个块里。假如我们求出了一个块,即已知 i[l,r]ni 都相等,我们珂以把这个块理解为一个长方形,长为 rl+1 宽为 n/l,答案就是面积。考虑求出下一个块,结论:设已知块为 [l,r],则新块为 [r+1,n/(n/l)],证明:

ll ans=0,l=1,r;
for( ;l<=n; ){
	r=n/(n/l);
	ans=(ans+(r-l+1)*(n/l))%mod;
	l=r+1;
}
return ans;

一个题

珂以将 ink%i 的取模部分转化为 kiki,这样原式化为 kniniki。有一个trick:我们要求 inf(i)kif(i) 表示某数论函数。一个块内的答案其实就是 kl× 函数对应区间和,这个题中我们直接等差数列求和就行。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=1145140,M=1919810,mod=10007;
ll n,k,tmp,num[N];
ll qpow(ll a,ll b){
	ll ans=1;
	while(b){
		if(b&1) ans=ans*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return ans;
}
ll ans=0,l=1,r;
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin>>n>>k;
	for( ;l<=n&&k/l; ){ //细节1,可能有0
		r=min(k/(k/l),n); //细节2,不要越界
		ans+=(k/l)*((l+r)*(r-l+1)/2);
		l=r+1;
	}
	cout<<n*k-ans;
	return 0;
}

莫比乌斯反演

定义

首先是定义莫比乌斯函数 μμ(n)={1n=10n(1)kkn

然后 μ(n) 是个积性函数,珂以线性筛来求,同时有两个结论:

  • d|nμ(n)={0n=11n1,即d|nμ(d)=ε(n),μ1=ε

  • 反演结论:[gcd(i,j)=1]=d|gcd(i,j)μ(d)=ε(gcd(i,j))

线性筛求 μ 的代码:

void calc(){
	mu[1]=1; //莫比乌斯函数
	for(int i=2;i<=5e4;++i){
		if(!vis[i]) pri[++cnt]=i,mu[i]=-1;
		for(int j=1;j<=cnt&&i*pri[j]<=5e4;++j){
			vis[i*pri[j]]=1;
			if(i%pri[j]==0){
				mu[i*pri[j]]=0;
				break;
			}
			mu[i*pri[j]]=-mu[i];
		}
	}
	for(int i=1;i<=5e4;++i) sum[i]=sum[i-1]+mu[i];
}
posted @   和蜀玩  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示