数论

(数论那玩意儿是谁发明的给我站出来)

感谢黄老师为我打开数论(绝望)的大门

 

进位计数制

 

b进制向十进制转换

乘以基数并展开:(按位权)

十进制向b进制转换

整数部分除以基数并倒取余数,小数部分乘以基数,并顺取整数部分。

例:0.7转二进制

0.7*2=1.4; -->0.1 //把个位数上的1扣粗来放在十分位

0.4*2=0.8; -->0.10 //0照样扣粗来

0.8*2=1.6; -->0.101

0.6*2=1.2; -->0.1011

……

例题

一个天平,砝码分别为1g、3g、9g、27g、…、6561g…,每个砝码只有一个,要称重的物品放在天平的左侧,而砝码允许放在天平的左右两侧。已知一个物品的质量N (N≤10^8),问如何称重?

(显然)1=(1)3,3=(10)3,9=(100)3,27=(1000)3……

只要将N转换成三进制,1表示需要这一位的砝码,0表示不要。

那么2呢……

其实2=(10-1)3,所以只要进一位,然后改为-1(在另一边放)即可。

 

回文数

 

十进制下回文数

int rev(int n) //算出n的逆序数 
{
	int s=0; 
	while(n){s=s*10+n%10;n/=10;} 
	return s; 
}
bool judge(int n) //判断n是否为回文数 
{
	int s=0,m=n; 
	while(n){s=s*10+n%10;n/=10;} 
	return s==m; 
}

b进制下回文数

bool judgeb(int n,int b) //判断n在b进制下是否为回文数 
{
	int s=0,m=n; 
	while (n>0) {s=s*b+n%b;n/=b;}
	//乘b加,表示将n按b进制下的逆序展开。
	return s==m; 
}

 

整除

 

定义

一个整数a能被另一个整数d整除,记作:d|a,意味着存在某个整数k,有a=kd。 0可被每个整数整除。若a>0且d|a,则|d|≤|a|。如果a|d,则我们称d是a的倍数,a是d的约数。

性质

若d|a,则对于任意整数k有d|ka 
若a|b且b|a,则有a=b    //对称性 
若c|b,b|a,则c|a          //传递性 
若c|a,d|b,则cd|ab 
若c|a,c|b,则c|(ma+nb) 
若n∈N*,则(a-b)|(an-bn)。 
若n为奇数,则(a+b)|(an+bn); 
若n为偶数,则(a+b)|(an-bn) 
任意n个连续正整数的乘积必能被n!整除

特殊

若2能整除a的最末位,则2|a;若4能整除a的最后两位,则4|a;若8能整除a的最后三位,则8|a。 
若3能整除a的各位数字之和,则3|a;若9能整除a的各位数字之和,则9|a。 
若5能整除a的最末位,则5|a;若25能整除a的最后两位,则25|a;若125能整除a的最后三位,则125|a。 
若11能整除a的偶位数字之和与奇位数字之和的差,则11|a。

 

快速幂

 

递归

int pow(int a, int b)//快速幂求a^b 
{
	if(b==0)return 1;//边界条件
	int tmp; 
	tmp=pow(a,b/2);//递归  
	tmp=(tmp*tmp); 
	if(b%2)//b是奇数  
	tmp=tmp*a; 
	return tmp; 
}

位运算

inline int pow(int a,int b)
{
    long long r=1,aa=a;
    while(b)
    {
        if(b&1)r=(r*aa)%mo;
        aa=(aa*aa)%mo;
        b>>=1;
    }
    return r;
}

 

素数和合数

 

素数

如果大于1的正整数p仅有的正因子是1和p, 则称p为素数

合数

大于1又不是素数的正整数称为合数

如果n是合数, 则n必有一个小于或等于n1/2的素因子

1~n的素数(埃式筛法)

2是素数, 删除2*2, 2*3, 2*4, …, 2*50 
第一个没被删除的是3, 删除3*3, 3*4,3*5,…,3*33 
第一个没被删除的是5, 删除5*5, 5*6, … 5*20 
得到素数p时, 需要删除p*p, p*(p+1), …p*[n/p]

算法时间复杂度O(nloglogn)

const int maxn=100000; 
bool isprime[maxn]; 
void searchPrime(int n) 
{
	memset(isprime,true,sizeof(isprime)); 
	isprime[1]=false; 
	for(i=2;i*i<=n;i++) 
		if(isprime(i))  
		{
			j=i*i; 
    		while(j<=maxn)isprime[j]=false,j+=i; 
		} 
}

素数判定

(未完待续……)

 

 

 

 

你可能感兴趣的:(未竟的事业,知识点梳理)