zoukankan      html  css  js  c++  java
  • 【数论笔记】

    前言

    跟数据结构和网络流奋战了好几天了,来和数论打了
    (毕竟我也是上物理课写出过国集反演题的人)
    可能更多的是笔记,题目少一点

    积性函数

    \(f\)是数论函数,若对于互质的\(a,b\)\(f(ab) = f(a)f(b)\),则称\(f\)为积性函数。
    若上式扩展到任意正整数,则称\(f\)为完全积性的
    由唯一分解定理,我们知道对于研究积性函数\(f\)可以转化成研究\(f(p^x)\)

    求值

    单点求值可以进行分解素因子
    如果要对\(1到n\)之间的所有的数求出\(f\),注意到\(Euler\)筛的过程中,可以求出每个数最小的素因子和最小素因子的幂次,因此可以在线性时间内求出\(f\)

    单位函数

    定义\(ϵ(n)\)
    \(ϵ(n) = [n = 1] = \left\{ \begin{aligned} 1,n = 1;\\ \ 0,n \not= 1; \end{aligned} \right.\)
    单位函数是完全积性函数

    除数函数

    \(σ_k(n) = \sum\limits_{d|n} d^k\)
    约数个数\(σ_0(n)\)常记为\(d(n)\)
    约数和\(σ_1(n)\)常记为\(σ(n)\)

    \(Euler函数\)

    \(\varphi(n) = n * \prod\limits_{i = 1}^{s}(1 - 1 / p_i)\)
    易见,该函数为积性函数

    性质

    \(n = \sum\limits_{d|n}\phi(d)\)
    \(\varphi(i * p)(p为质数)= \left\{\begin{array}{l} \varphi(i) * p,(i\mod p = 0) \\ varphi(i) *(p - 1),(i\mod p \not= 0) \end{array}\right.\)

    \(Dirichlet\)卷积

    \(f,g\)是数论函数,考虑\(h\)
    \(h(n) = \sum\limits_{d|n}f(d)g(n / d)\)
    \(h\)\(f和g\)\(Dirichlet\)卷积,记做\(h = f * g\),以下简称为卷积(

    性质

    \(ϵ\)为该卷积的单位元
    满足交换律和结合律
    如果\(f,g\)是积性函数,那个\(f * g\)也是积性函数
    定义幂函数
    \(Id_k(n) = n ^ k,Id = Id_1\)
    那么除数函数的定义
    \(σ_k = 1 * Id_k\)
    \(Euler\)函数定义
    \(Id = \phi * 1\)

    计算

    \(f,g\)为数论函数,计算他们的卷积在\(n\)处的值,枚举\(n\)的所有约数
    计算\(f,g\)卷积的前\(n\)项,可以枚举\(1到n\)的每个数的倍数,根据调和级数的结论,这样是\(O(nlogn)\)

    [SDOI2012]Longge 的问题:

    [SDOI2012]Longge 的问题

    \(\sum\limits_{i = 1}^n gcd(i,n) = \sum\limits_{d|n}d\sum\limits_{i = 1} ^ {n}[gcd(i,n) == d]\\=\sum\limits_{d|n}d\sum\limits_{i = 1} ^ {n / d}[gcd(i,n / d) == 1]\\=\sum\limits_{d|n}d\varphi(n/d)\)

    代码

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #define ll long long
    
    ll n;
    
    ll phi(ll now){
    	ll ans = now;
    	for(ll i = 2;i * i <= now;++i){
    		if(now % i == 0){
    			ans = ans / i * (i - 1);
    			while(now % i == 0) now /= i;
    		}
    	}
    	if(now > 1) ans = ans / now * (now - 1);
    	return ans;
    }
    
    ll ans = 0;
    
    int main(){
    	scanf("%lld",&n);
    	ll s = sqrt(n);
    	for(ll i = 1;i <= s;++i){
    		if(n % i == 0){
    			ans += phi(n / i) * i;
    			if(i * i != n)
    			ans += phi(i) * (n / i);
    		}
    	}
    	std::cout<<ans<<std::endl;
    }
    

    \(Mobius\)函数

    \(\mu(n) = \left\{\begin{array}{l} 1,n = 1; \\ (-1) ^ 2,n = p_1p_2....p_s \\ 0 otherwise; \end{array}\right.\)
    其中\(p_1,....p_s\)是不同素数
    可以看出,\(\mu(n)恰在n无平方因子是非零\)
    易见\(\mu\)为积性函数。

    性质

    \(\mu * 1 = ϵ\)

    \(Mobius\)变换

    \(g = f * 1\)\(g\)\(f\)\(Mobius\)变换

    \(Mobius\)反演

    \(g = f * 1\)
    \(f = g * \mu\)
    证明:
    \(g = f * 1 \iff f = f * ϵ = f * 1 * \mu = g * \mu\)

    结论

    \(\mu(ab) = \mu(a)\mu(b)[(a,b) == 1]\)

    YY 的 GCD

    YY 的 GCD

    \(\sum\limits_{p \in P}\sum\limits_{x = 1} ^ n\sum\limits_{y = 1}^m[gcd(x,y)=p] = \sum\limits_{p \in P}\sum\limits_{x = 1} ^ {n / p}\sum\limits_{y = 1}^{m/p}[gcd(x,y)=1]\\=\sum\limits_{p \in P}\sum\limits_{x = 1} ^ {n / p}\sum\limits_{y = 1}^{m/p}\sum\limits_{d|x,d|y}\mu(d)\\=\sum\limits_{p \in P} \sum\limits_{d = 1} ^ {\lfloor{min(n,m) / p}\rfloor}\mu(d)\lfloor n / pd \rfloor\lfloor m / pd \rfloor \\= \sum\limits_{t = 1}^{min(n,m)}\lfloor n / t \rfloor\lfloor m / t \rfloor\sum\limits_{p \in P,p | t}\mu(\frac{t}{p})\)

    \(\sum\limits_{p \in P,p | t}\mu(\frac{t}{p})\)设为\(g(t)\)
    同时令\(f(n) = [n \in P]\)
    所以\(g = f * \mu\)
    直接计算\(g\)和前缀和,然后计算,时间为\(O(nloglogn)\)
    代码

    #include<iostream>
    #include<cstdio>
    #define ll long long
    
    ll mu[10000010];
    int flag[10000010],prime[10000010],cnt,f[10000010],sum[10000010];
    
    void sieve(){
    	mu[1] = 1;
    	for(int i = 2;i <= 10000000;++i){
    		if(!flag[i]) prime[++cnt] = i,mu[i] = -1;
    		for(int j = 1;j <= cnt && i * prime[j] <= 10000000;++j){
    			flag[i * prime[j]] = 1;
    			if(i % prime[j] == 0) break;
    			mu[i * prime[j]] = -mu[i];
    		}
    	}
    	for(int i = 1;i <= cnt;++i)
    	for(int j = 1;prime[i] * j <= 10000000;++j)
    	f[j * prime[i]] += mu[j];
    	for(int i = 1;i <= 10000000;++i)
    	sum[i] = sum[i - 1] + f[i];
    }
    
    ll solve(int a,int b){
    	ll ans = 0;
    	if(a > b) std::swap(a,b);
    	for(int l = 1,r = 0;l <= a;l = r + 1){
    		r = std::min((a / (a / l)),(b / (b / l)));
    		ans += 1ll * (sum[r] - sum[l - 1]) * 1ll * (a / l) * 1ll * (b / l);
    	}
    	return ans;
    }
    
    int main(){
    	sieve();
    	int n,m,T;
    	scanf("%d",&T);
    	while(T -- ){
    		scanf("%d%d",&n,&m);
    		std::cout<<solve(n,m)<<std::endl;
    	}
    }
    

    [SDOI2015] 约数个数和

    [SDOI2015] 约数个数和
    左转题解
    题解

    杜教筛

    我觉得杜教筛值得我写在另一篇里

    杂项:

    \(Euler\)定理

    \(a ^ {\varphi(n)} = 1 (mod\ n)\)
    \(a ^ n = a ^ {m\ mod \ \varphi(n) + \varphi(n)} = 1 (mod\ n)\)

    \(Lucas\)定理

    对于组合数膜上一个质数,有
    \(C_{n}^{m} = (C_{n \ mod\ p}^{m \ mod\ p})(C_{\lfloor \frac{n}{p} \rfloor}^{\lfloor \frac{m}{p} \rfloor})(mod\ p)\)

  • 相关阅读:
    Python之CVXOPT模块
    JavaScript之读取和写入cookie
    jQuery学习(2)ajax()使用
    JavaScript之使用AJAX(适合初学者)
    Jquery焦点图实例
    jquery-mobile表单提交问题
    程序员笔记|Spring IoC、面向切面编程、事务管理等Spring基本概念详解
    使用什么调试swoole程序
    swoole模块的编译安装:php编译安装swoole模块的代码
    TP5使用Redis处理电商秒杀
  • 原文地址:https://www.cnblogs.com/dixiao/p/14508133.html
Copyright © 2011-2022 走看看