DAY-3 : 简单数论

本文探讨了数论中的基本概念,如欧拉函数及其性质,并提供了多种求解欧拉函数值的方法,包括打表法及利用积性函数性质进行优化。

专题:简单数论

我今天一定是学数学来的。学完我觉得我都可以参加数学竞赛了。晕头转向,哪哪都没学过。

Question_A

    考察欧拉函数,打表打表!!!

    普通打表太慢了,要用什么筛法,我学了学百度百科的打表方法,感觉好神奇哦,直接使用了三个性质没有套用求解公式,那样循环居然每个数都能走一遍(而且那个素数判断也镶嵌在其中太神奇了吧),但感觉有的会重复计算;然后还看了看其他人的打表方法大部分都用了那个公式,也是筛法;迷……

     欧拉函数是指:对于一个正整数n,小于n且和n互质的正整数(包括1)的个数,记作φ(n) 。

     通式:φ(x)=x*(1-1/p1)*(1-1/p2)*(1-1/p3)*(1-1/p4)…..(1-1/pn),其中p1, p2……pn为x的所有质因数,x是不为0的整数。φ(1)=1        (唯       一和1互质的数就是1本身)。

    对于质数p,φ(p) = p - 1。注意φ(1)=1.

    欧拉定理:对于互质的正整数a和n,有aφ(n) ≡ 1 mod n。

    欧拉函数是积性函数——若m,n互质,φ(mn)=φ(m)φ(n)。 

     若n是质数p的k次幂,φ(n)=p^k-p^(k-1)=(p-1)p^(k-1),因为除了p的倍数外,其他数都跟n互质。

    特殊性质:当n为奇数时,φ(2n)=φ(n)

    欧拉函数还有这样的性质:

    设a为N的质因数,若(N % a == 0 && (N / a) % a == 0) 则有E(N)=E(N / a) * a;若(N % a == 0 && (N / a) % a != 0) 则有:E         (N) =      E(N / a) * (a - 1)。

    参考链接:www.cnblogs.com/soTired/p/4764321.html

    附:百度百科上的打表模板:

/*
特性 :
1.若a为质数,phi[a]=a-1;
2.若a为质数,b mod a=0,phi[a*b]=phi[b]*a
3.若a,b互质,phi[a*b]=phi[a]*phi[b](当a为质数时,if b mod a!=0 ,phi[a*b]=phi[a]*phi[b])
*/
int m[n],phi[n],p[n],nump;
//m[i]标记i是否为素数,0为素数,1不为素数;p是存放素数的数组;nump是当前素数个数;phi[i]为欧拉函数
int make()
{
        phi[1]=1;
    for (int i=2;i<=n;i++)
    {
        if (!m[i])//i为素数
        {
            p[++nump]=i;//将i加入素数数组p中
            phi[i]=i-1;//因为i是素数,由特性得知    
        }    
        for (int j=1;j<=nump&&p[j]*i<n;j++)  //用当前已的到的素数数组p筛,筛去p[j]*i
        {
            m[p[j]*i]=1;//可以确定i*p[j]不是素数 
            if (i%p[j]==0) //看p[j]是否是i的约数,因为素数p[j],等于判断i和p[j]是否互质 
            {
                phi[p[j]*i]=phi[i]*p[j]; //特性2
                break;
            }
            else phi[p[j]*i]=phi[i]*(p[j]-1); //互质,特性3其,p[j]-1就是phi[p[j]]   
        }
    }
}

  

Question_B

    你敢相信么我题意看不懂,什么是约数、还是叫因数。。查了半天。  直接看定义比较明了;

    1)一个正整数n按素因子分解:n=p1^a1*p2^a2*....*pk^ak,那么n的约数的个数为(a1+1)(a2+1)...(ak+1);

    2)对于一个素数p,n!中按素因子分解,p的幂为 n/p+n/p^2+n/p^3...,其中/为整除

    3)C(N,K)=N! / (K! (N-K)!)       整体约数个数f(N!) - f(K!) - f((N-K)!).

    还有就是,cout 输出时间和 printf 怎么差这么多,前者450ms,后者625ms。

    本题上代码,因为太多知识点了

#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

int primes[341];
int numpr;

bool jupr(int n){
	for(int i=2;i*i<=n;i++)
	    if(n%i==0)
                return false;
	return true;
}

void prime(){
	for(int i=2;i<=432;i++)
		if(jupr(i))
			primes[numpr++]=i;
}

int cal(int a,int b){
	int sum=0;
	int flag=b;
	while(a>=b){
	    sum+=a/b;
	    b*=flag;
	}
	return sum;
}

int main(){
	prime();
	int n,k;
	while(~scanf("%d%d",&n,&k)){
		long long ans=1;
		for(int i=0;i<numpr&&primes[i]<=max(n,k);i++){
		    int a = cal(n,primes[i]);
                    int b = cal(k,primes[i]);
                    int c = cal(n-k,primes[i]);
                    ans*=(a-b-c+1);
		}
		printf("%lld\n",ans);
	}
}

Question_C

    什么积性函数性质啊,不会,只学会了最弱鸡的方法,欧拉啊欧拉,wuwuwu。

    欧拉函数 φ(x)φ(x) :1到x-1有几个和x互质的数。

    gcd(i,n)必定是n的一个约数。

    若p是n的约数,那么gcd(i,n)==p的有φ(n/p)φ(n/p)个数,因为要使gcd(i,n)==p,i/p和n/p必须是互质的。

    那么就是求i/p和n/p互质的i在[1,n]里有几个,就等价于 1/p,2/p,...,n/p 里面有几个和n/p互质,即φ(n/p)。

    求和的话,约数为p的有φ(n/p),所以就是p*φ(n/p),同时把约数为n/p的加上去,i*i==n特判一下。

    参考链接:https://www.cnblogs.com/flipped/p/5690123.html

    太难了吧这也.......

#include<cstdio>
#include<cmath>
long long eular(int x){
	int rea=x;
	for(int i=2;i<=sqrt(x);i++){
		if(x%i==0){
			rea=rea/i*(i-1);
			while(x%i==0)
				x=x/i;
		}
	}
	if(x>1)
		rea=rea/x*(x-1);
	return rea;
}

int main(){
	long long n;
	while(~scanf("%lld",&n)){
		long long ans=0;
		long long i;
		for( i=1;i<sqrt(n);i++){
			if(n%i==0)
				ans+=i*eular(n/i)+n/i * eular(i);
		}
		if(i*i==n)
			ans+=i*eular(i);
		printf("%lld\n",ans);
	}
}

    后来看了看积性性质大概就公式吧 ,没太懂:f(n)=n*∏(1+ai*(pi-1)/pi

#include <iostream>
using namespace std;
typedef long long ll;
 
int main()
{
	ll n;
	while(scanf("%lld",&n)==1){
		ll ans=n;
		for(ll i=2;i*i<=n;++i){
			if(n%i==0){
				ll a=0,p=i;
				while(n%p==0){
					++a;
					n/=p;
				}
				ans=ans+ans*a*(p-1)/p;
			} 
		}
		if(n!=1)
			ans=ans+ans*(n-1)/n;
		printf("%I64d\n",ans);
	}	
	return 0;	
}

   。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

Question_E

    欧几里德算法又称辗转相除法,是指用于计算两个正整数a,b的最大公约数。应用领域有数学和计算机两个方面。计算公式gcd(a,b) = gcd(b,a mod b)。

    转化为gcd(b×t+a,b)=gcd(a,b)(t为任意整数)

    刚开始一直 Runtime Error  ,   (sum-1)的值没把握好。

-- BONUS: FizzBuzz -- --------------- -- &#39;Fizz buzz is a group word game for children to teach them about division. Players take turns to count incrementally, replacing any number divisible by three with the word "fizz", and any number divisible by five with the word "buzz", and any number divisible by both three and five with the word "fizzbuzz".&#39; -- https://en.wikipedia.org/wiki/Fizz_buzz fizzbuzzBruteForce x = case x of 1 -> "1" 2 -> "2" 3 -> "Fizz" 4 -> "4" 5 -> "Buzz" -- ... _ -> "Let&#39;s try something else" -- Quick modular arithmetic intro for those unfamiliar: -- Q: If it&#39;s 11 o&#39;clock now, what time will it be in 2 hours? -- A: 1 o&#39;clock -- Surprise! You&#39;ve been doing &#39;modulo 12&#39; arithmetic your whole life. -- >>> (11 + 2) `mod` 12 -- 1 -- For &#39;divisible by 3&#39; we use modulo 3 arithmetic: -- >>> 0 `mod` 3 -- 0 -- >>> 1 `mod` 3 -- 1 -- >>> 2 `mod` 3 -- 2 -- >>> 3 `mod` 3 -- 0 -- >>> 6 `mod` 3 -- 0 -- Q: What&#39;s the output when the input is divisible by 3? -- A: 0 divisibleBy3 x = x `mod` 3 == 0 -- >>> divisibleBy3 2 -- False -- >>> divisibleBy3 6 -- True -- Q: How do we define `divisibleBy5`? -- A: divisibleBy5 x = x `mod` 5 == 0 fizzbuzz x | divisibleBy3 x && divisibleBy5 x = "FizzBuzz" | divisibleBy3 x = "Fizz" | divisibleBy5 x = "Buzz" | otherwise = show x fizzbuzz&#39; x = case divisibleBy3 x of True -> case divisibleBy5 x of True -> "FizzBuzz" False -> "Fizz" False -> case divisibleBy5 x of True -> "Buzz" False -> show x 总结这些代码在讲些什么
最新发布
10-09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值