关于数论的一点整理(看心情更新)

一、欧拉函数的求法

欧拉函数表示一个数的简化剩余系的元素数。
对于一个数p,它的欧拉函数值即为[1,p)内与p互质的数的个数
数组形式一般是Phi(x)

1、O(√n)求φ(n)

int zch(int x) {
    
    
	int ret=x;
	for(int i=2;i*i<=x;i++){
    
    
		if(x%i==0)	ret-=ret/i;
		while(x%i==0)	x/=i;
	}
	if(x>1)	ret-=ret/x;
	return ret;
}

2、O(n)求φ(1)~φ(n)

const int maxn=1e6+7;
int cnt,v[maxn],p[maxn],phi[maxn];
void PHI(int n){
    
    
	for(int i=2;i<=n;i++) {
    
    
		if(!v[i]){
    
    
			p[++cnt]=i;
			phi[i]=i-1;
			v[i]=i;
		}
		for(int j=1;j<=cnt;j++){
    
    
			if(1ll*p[j]*i>n) break;
			int t=p[j]*i;
			v[t]=p[j];
			if(i%p[j]==0){
    
    
				phi[t]=phi[i]*p[j];
				break;
			}
			else phi[t]=phi[i]*phi[p[j]];
		}
	}
}

讲解:欧拉函数详解

3、所有不是质数的数的最小质因子是2或3或5或7。再细分如果n是偶数则它的最小素因子是2,如果n是奇数,它的最小素因子是3/5/7。

4、欧拉函数中有一个推论:1到n中与n互质的和==phi(n)*n/2。 可以看一下 证明

一道欧拉函数与容斥相结合的题:hdu-5514 -----这题挺有意思的

5、扩展欧拉定理
情况一:

降幂公式一 

(a,p)==1,a^b==a^(b % φ(p)) 
若q为素数, a^b==a^(b % (p-1) )

例 
求 2^n % mod , 已知mod为素数 

ll qpow(ll a, int b){
    
    
	ll ans=1;
	while(b){
    
    
		if(b&1) ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}

string a;
ll ans;
int main(){
    
    
	cin>>a;
	int n=a.size();
	for(int i=0;i<n;i++)	ans=(ans*10+a[i]-'0')%(mod-1);
	cout<<qpow(2,ans);
}

情况二:


降幂公式二、三 

求 a^b mod p 
1<=a<=1e9 , 1<=b<=1e2000000 , 1<=p<=1e8
扩展欧拉定理模板
 
int a,b,p,phi;
char x;
bool f;
ll qpow(ll a, int b){
    
    
	ll ans=1;
	while(b){
    
    
		if(b&1) ans=(ans*a)%p;
		a=(a*a)%p;
		b>>=1;
	}
	return ans;
}
ll zch(int x) {
    
    
	ll ret=x;
	for(ll i=2;i*i<=x;i++){
    
    
		if(x%i==0)	ret-=ret/i;
		while(x%i==0)	x/=i;
	}
	if(x>1)	ret-=ret/x;
	return ret;
}
int main(){
    
    
	scanf("%d%d",&a,&p);
	phi=zch(p);
	while(!isdigit(x=getchar()));
	while(isdigit(x)){
    
    
		b=b*10+x-'0';
		if(b>=phi){
    
    
			f=1;
			b%=phi;
		}
		x=getchar();
	}
	if(f)	b+=phi;
	printf("%lld",qpow(a,b));
}


二、莫比乌斯函数
莫比乌斯函数讲解
1、莫比乌斯函数的线性筛(就比普通线性筛多4行)

const int maxn=1e5+7;
int prime[maxn],cnt,mu[maxn];	//保存质数 , 质数的个数 , 保存n的莫比乌斯函数值
bool judge[maxn];				//标记是否为质数,true表示是质数,flase表示合数;
void mul(){
    
    
	mu[1]=1;
	for(int i=2;i<=maxn;i++){
    
    
		if(judge[i]){
    
    
			prime[++cnt]=i;
			mu[i]=-1;
		}
		for(int j=1;j<=cnt&&i*prime[j]<maxn;j++){
    
    
			judge[i*prime[j]]=0;
			if(i%prime[j]==0){
    
    
				mu[i*prime[j]]=0;
				break;
			}
			else	mu[i*prime[j]]=-mu[i];
		}
	}
}

做题注意点:

1、数学几何中,数据往往是double,比较两个数是否相等,得用fabs(a,b)<1e-10.

2、已知两条直线的各两个点(共4个点),求交点时,不要用斜率做,除法太多,数据会卡精度。有公式:见例题

3、 atan 和 atan2 都是求反正切函数,如:有两个点 point(x1,y1), 和 point(x2,y2);
那么这两个点形成的斜率的角度计算方法分别是:
float angle = atan( (y2-y1)/(x2-x1) );

float angle = atan2( y2-y1, x2-x1 );

atan 和 atan2 区别:
1:参数的填写方式不同;
2:atan2 的优点在于 如果 x2-x1等于0 依然可以计算,但是atan函数就会导致程序出错;

结论: atan 和 atan2函数,建议用 atan2函数;

4、acos() 函数返回一个数的反余弦。
提示:acos(-1) 返回 Pi 的值。

acos(number);
• number	
• 必需。
• 规定一个数,范围在 -11 之间。

• 返回值
• number 的反余弦。
• 如果 number 不在 -11 之间的范围,则返回 NAN。

有一道用到上述三角函数的题:链接

猜你喜欢

转载自blog.csdn.net/weixin_45606191/article/details/107522944