数论基础学习总结(持续补充中)

数论基础

算术基本定理(唯一分解定理)

任何一个大于1的自然数都可以唯一分解成有限个素数的乘积

$N=p_1^{a_1}\times p_2^{a_2}\times...\times p_n^{a_n} | p_1<p_2<...<p_n ,a_i\in Z$

上式中$p_i$为素数

有关素数筛

埃式筛法

就是拿一个已经筛选出的素数去排掉其他的数,比如2是素数,就用他筛掉2*2,2*3,2*4……,3是素数,就用他筛掉3*2,3*3,3*4……,把每个素数的倍数都筛掉,不过我们发现,3*2事实上已经在2的时候筛掉过了,即比这个数小的倍数都已经被筛过了,所以我们只要从这个数的平方开始筛就可以了。这个筛法最容易理解也最好写,一定要会写!经过这个筛法,能打素数表,能判定一个数是不是素数。复杂度O(nloglogn)。也可以用这种筛法筛出因子。

 1 const int N=1e6+7;
 2 bool isprime[N];
 3 int prime[N];//储存素数,打表
 4 void db()
 5 {
 6     memset(isprime,1,sizeof(isprime));//这步事实上不太好,不过因为是bool类型所以不影响结果
 7     isprime[0]=isprime[1]=0;
 8     int cntp=0;
 9     for(long long i=2;i<N;i++)
10     {
11         if(isprime[i])
12         {
13             prime[cntp++]=i;
14             for(long long j=i*i;j<N;j+=i)//i*i会爆int所以用ll
15                 isprime[j]=0;
16         }
17     }
18 }

埃式筛法

欧拉线性筛法

正常情况下就算是没有优化的埃式筛法应该也是够用的,但是我们发现埃式筛法还是不是最快的,比如12这个数会被2和3筛两次,诸如此类的重复会降低效率。所以我们给出欧拉线性筛法。这个筛法自然比较难理解一点,其思路是这样的,从2开始,将这个素数和之前筛出的所有素数的乘积都判负,如果碰到i是一个合数,也用他去筛,但在筛的循环中碰到一个是他因子的素数就跳出(一个合数必定能表示成至少一个素数参与的分解式),达到避免重复筛的目的,然后一个循环后就筛出了素数。这个方法比较难理解,我也不是很能感受到这个方法的正确性,不过据说用反证法能进行证明。复杂度O(n)。

线性筛还能用在处理其他积性函数上。

 1 const int N=1e6+7;
 2 bool isprime[N];
 3 int prime[N];
 4 void db()
 5 {
 6     memset(isprime,1,sizeof(isprime));
 7     isprime[0]=isprime[1]=0;
 8     int cntp=0;
 9     for(int i=2;i<N;i++)
10     {
11         if(isprime[i])
12             prime[cntp++]=i;
13     //这一部分是精髓所在也是难理解的部分,不管i是否是素数,都进循环去筛,i是合数时中途会跳出,达到减少重复筛的目的
14         for(int j=0;j<cntp&&i*prime[j]<N;j++)
15         {
16             isprime[i*prime[j]]=0;
17             if(!(i%prime[j]))
18                 break;
19         }
20     }
21 }

欧拉线性筛

有关因子

求因子个数

前置定理:若p是一个素数,a是一个正整数,那么有$\tau(p^a)=a+1$。

定理:若正整数n有质因数分解$n=p_1^{a_1}\times p_2^{a_2}\times...\times p_k^{a_k}$,则$\tau(n)=(a_1+1)\times(a_2+1)\times...\times(a_k+1)$。

我们需要先打出一张素数表才能套用这个。

 1 int factor_count(int n)
 2 {
 3     int ans=1;
 4     int cnt;
 5     int k=sqrt(n)+1;
 6     for(int i=0;prime[i]<k;i++)
 7     {
 8         if(n%prime[i]==0)
 9         {
10             cnt=0;
11             while(n%prime[i]==0)
12             {
13                 cnt++;
14                 n/=prime[i];
15             }
16             ans*=(cnt+1);
17         }
18     }
19     if(n>1)//这一步是因为只筛到根号n,可能会留最后一个因子,此时需要再算上这个因子
20         ans*=2;
21     return ans;
22 }

求因子个数

素因子筛

利用埃式筛法处理,复杂度O(nloglogn)

 1 const int maxn=1e5+7;
 2 void db()
 3 {
 4     vector<int> d[maxn];
 5     for(int i=2;i<maxn;i++)
 6         if(d[i].empty())
 7         {
 8             for(int j=2*i;j<maxn;j+=i)
 9                 d[j].push_back(i);
10         }
11 }

素因子筛

有关GCD

辗转相除法

1 long long gcd(long long a,long long b)
2 {
3     return b?gcd(b,a%b):a;
4 }

GCD

扩展欧几里得

 1 long long exgcd(long long a,long long b,long long &x,long long &y)
 2 {
 3     if(b==0)
 4     {
 5         x=1,y=0;
 6         return a;
 7     }
 8     long long gcd=exgcd(b,a%b,y,x);
 9     y-=a/b*x;
10     return gcd;
11 }

exgcd

原文地址:https://www.cnblogs.com/computer-luo/p/9459404.html

时间: 2024-08-12 00:45:44

数论基础学习总结(持续补充中)的相关文章

linux学习资料持续更新中

一.LINUX基础教程 1.老男孩系列免费视频: 1) linux高薪入门实战视频教程(第二部)老男孩linux教程 http://edu.51cto.com/course/course_id-1035-page-1.html 2) 跟着老男孩从0开始一步步实战深入学习linux运维(三) http://edu.51cto.com/lesson/id-11909.html linux学习资料持续更新中,布布扣,bubuko.com

[原]零基础学习视频解码之FFMpeg中比较重要的函数以及数据结构

在正式开始解码练习前先了解下关于FFmpeg中比较重要的函数以及数据结构. 1. 数据结构:  (1) AVFormatContext  AVFormatContext是一个贯穿始终的数据结构,很多函数都要用到它作为参数.FFmpeg代码中对这个数据结构的注释是:format I/O context 此结构包含了一个视频流的格式内容.其中存有了AVInputFormat(or AVOutputFormat同一时间AVFormatContext内只能存在其中一个),和AVStream.AVPack

nodejs学习(持续更新中)

nodejs和express的安装什么的,网上基本都有现成的了,这里有点说下, 在较早点的版本(如3.5.0) npm install -g [email protected] 后,可以直接使用 express helloWorld创建工程, 但最新express4.0版本中将命令工具分家出来了(项目地址:https://github.com/expressjs/generator),所以我们还需要安装一个命令工具,命令如下:npm install -g express-generator ##

jquery写插件的几种写法总结(持续补充中)

1:jQuery.fn.extend(object);  给jQuery对象添加方法. js封装文件示例 $.fn.extend({ alertWhileClick:function(){ $(this).click(function(){ alert($(this).val()); }); } }); HTML中的js调用 $(“#input1″).alertWhileClick(); HTML代码 <input id=”input1″ type=”text”/> 2:jQuery.exte

[Hadoop] Hadoop学习历程 [持续更新中…]

1. Hadoop FS Shell Hadoop之所以可以实现分布式计算,主要的原因之一是因为其背后的分布式文件系统(HDFS).所以,对于Hadoop的文件操作需要有一套全新的shell指令来完成,而这就是Hadoop FS Shell.它主要是用于对Hadoop平台进行文件系统的管理. 有关HDFS的介绍博客请移步:Hadoop学习笔记之Hadoop基础. 有关Hadoop FS Shell的学习文档:Hadoop FS Shell学习文档. 2. Hadoop Streaming 我们知

【Java基础学习笔记】Java中Socket+Swing设计简单通信

在<Java从入门到精通(第3版)>的原书中,客户端仅能发送一次数据,我在此基础上修改了一点点,实现了多次发送数据的单向通讯. 1. 服务器端 package Tcp_IP; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import java.sq

零基础学习视频解码之FFMpeg中比较重要的函数以及数据结构(转)

在正式开始解码练习前先了解下关于FFmpeg中比较重要的函数以及数据结构. 1. 数据结构:  (1) AVFormatContext  AVFormatContext是一个贯穿始终的数据结构,很多函数都要用到它作为参数.FFmpeg代码中对这个数据结构的注释是:format I/O context 此结构包含了一个视频流的格式内容.其中存有了AVInputFormat(or AVOutputFormat同一时间AVFormatContext内只能存在其中一个),和AVStream.AVPack

【jQuery基础学习】04 jQuery中的表格操作及cookie插件的使用

这章本来准备写成jQuery的表单操作和表格操作的. 然而昨天吧jQuery的表单操作看完,发现全部在炒之前章节的剩饭,所以就没写出来. 那么今天就来看看表格吧. 因为平常做的都是公司的内部管理系统,所以说数据表格用到的还是比较多的.那么在这里写出来说不定还能用上. 关于jQuery的表格应用 隔行变色 $(function(){ $("tbody>tr:odd").addClass("样式1");//odd是选取奇数行 $("tbody>tr

Pyqt 基础功能 (持续更新中……)

总结Pyqt的基础知识 1. Pyqt  设置禁止最大化及禁止拖拽窗口大小 1 # PyQT禁止窗口最大化按钮: 2 self.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint) 3 # PyQT禁止调整窗口大小: 4 self.setFixedSize(self.width(), self.height()) 2.