本文主要是介绍SDAU暑假训练第二天----------数论(2)(2018/7/31),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
今天上午还是看数论,下午有场练习赛,A了四个题,不是很难,个别题有点难想,比如逆向思维那个,另外读题能力很重要!!
目录
同余
同余式基本概念
同余的运算性质:
剩余类(只整理基础,复杂的剩余环涉及到了近世代数理论)
费马小定理
欧拉定理
1.欧拉函数的线性筛法(类比素数的线性筛法)
2.欧拉线性筛法求素数
同余
同余式基本概念
设m是大于1的正整数,a、b是整数,如果(a-b)|m,则称a与b关于模m同余,记作a≡b(mod m),读作a与b对模m同余。
显然,有以下事实
(1)若a≡0(mod m),则a|m;
(2)a≡b(mod m)等价于a与b分别用m去除,余数相同。
同余的运算性质:
1.反身性:a≡a (mod m);
2.对称性:若a≡b(mod m),则b≡a (mod m);
3.传递性:若a≡b(mod m),b≡c(mod m),则a≡c(mod m);
4.同余式相加/减:若a≡b(mod m),c≡d(mod m),则a+c≡b+d(mod m);a-c≡b-d(mod m);
5.同余式相乘:若a≡b(mod m),c≡d(mod m),则ac≡bd(mod m)。
6.线性运算:如果a ≡ b (mod m),c ≡ d (mod m),那么
(1)a ± c ≡ b ± d (mod m);
(2)a * c ≡ b * d (mod m)。
除法:若 ,则 ,其中gcd(c,m)表示c和m的最大公约数,
特殊地, 则 ;
8.幂运算:如果 ,那么 ;
9.若 ,n=m,则 ;
10.若 ,(i=1,2...n) 则 ,其中 表示m1,m2,...mn的最小公倍数。
剩余类(只整理基础,复杂的剩余环涉及到了近世代数理论)
剩余类,设模为n,则根据余数可将所有的整数分为n类,把所有与整数a模n同余的整数构成的集合叫做模n的一个剩余类,记作[a]。并把a叫作剩余类[a]的一个代表元。
一个整数被正整数n除后,余数有n种情形:0,1,2,3,…,n-1,它们彼此对模n不同余。这表明,每个整数恰与这n个整数中某一个对模n同余。这样一来,按模n是否同余对整数集进行分类,可以将整数集分成n个两两不相交的子集。我们把(所有)对模n同余的整数构成的一个集合叫做模n的一个剩余类。每一个整数必包含在而且仅包含在上述一个集合里。②两个整数同在一个集合的充分必要条件是它们对模□同余。
剩余类的相关运算性质
交换律:([a]+[b])+[c]=[a]+([b]+[c])
交换律:[a]+[b]=[b]+[a]
分配率:[a]([b]+[c])=[a][b]+[a][c]
此外加减法:[a]+[0]=[0]+[a]=[a] 乘法: [a][0]=[0][a]=[0] [0]叫做零元 [a][1]=[1][a]=[a] [1]叫做单位元
费马小定理
假如p是质数,且gcd(a,p)=1,那么 a^(p-1)≡1(mod p),例如:假如a是整数,p是质数,则a,p显然互质(即两者只有一个公约数1),那么我们可以得到费马小定理的一个特例,即当p为质数时候, a^(p-1)≡1(mod p)。
例题1:https://blog.csdn.net/zcy_2016/article/details/55054146
例题2:利用费马小定理计算
除以13的余数
欧拉定理
欧拉定理,(也称费马-欧拉定理)是一个关于同余的性质。欧拉定理表明,若n,a为正整数,且n,a互质,则:
(对于正整数N,代表小于等于N的与N互质的数的个数,记作φ(N))
1.欧拉函数的线性筛法(类比素数的线性筛法)
线性时间内求出1~N的所有φ 有以下三条性质:
①:φ(p)=p-1
②:φ(p*i)=p*φ(i) (当p%i==0时)
③:φ(p*i)=(p-1)*φ(i) (当p%i!=0时)
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int prime[100001],mark[1000001];//prime是素数数组,mark为标记不是素数的数组
int tot,phi[100001];//phi为φ(),tot为1~i现求出的素数个数
void getphi(int N){phi[1]=1;//φ(1)=1for(int i=2;i<=N;i++){//从2枚举到Nif(!mark[i]){//如果是素数prime[++tot]=i;//那么进素数数组,指针加1phi[i]=i-1;//根据性质1所得}for(int j=1;j<=tot;j++){//从现求出素数枚举if(i*prime[j]>N) break;//如果超出了所求范围就没有意义了mark[i*prime[j]]=1;//标记i*prime[j]不是素数if(i%prime[j]==0){//应用性质2phi[i*prime[j]]=phi[i]*prime[j];break;}else phi[i*prime[j]]=phi[i]*phi[prime[j]];//应用性质3}}
}
int N;
int main(){cin>>N;getphi(N);for(int i=1;i<=N;i++){cout<<i<<":phi ( "<<phi[i]<<" )"<<endl;//输出phi(i)}
}
2.欧拉线性筛法求素数
求素数原来的经典埃拉特斯特尼筛法:时间复杂度为O(n loglog n)
void GetEven()
{int t=sqrt(N);for(int i=3; i<=t;i++){if(prime[i])for(int j=i*i; j <= N; j+=i)//筛掉i的倍数 prime[j]=false;}
欧拉线性筛法
const int MAXN=3000001;
int prime[MAXN];//保存素数
bool vis[MAXN];//初始化
int Prime(int n)
{int cnt=0;memset(vis,0,sizeof(vis));for(int i=2;i<n;i++){if(!vis[i])prime[cnt++]=i;for(int j=0;j<cnt&&i*prime[j]<n;j++){vis[i*prime[j]]=1;if(i%prime[j]==0)//关键 break;}}return cnt;//返回小于n的素数的个数
}
这篇关于SDAU暑假训练第二天----------数论(2)(2018/7/31)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!