- 欧拉公式:
<span style="font-size:18px;">int oula(int n)//求1到n-1间有多少跟n互质 { int num=1,i; for(i=2;i*i<=n;i++) { if(n%i==0) { n/=i; num*=i-1; while(n%i==0) { n/=i; num*=i; } } } if(n>1) num*=n-1; return 0; } 补充一点结论:这num个数的和为n/2*num</span>
- 求最大公约数:
<span style="font-size:18px;">int gcd(int a,int b)(共产党原理是求a,b最大公约数) { while(b) { int r=a%b; a=b; b=r; } return a; } 以上代码也可以略为一行:return b?gcd(b,a%b):a;</span>
- 素筛(筛选出素数):
<span style="font-size:18px;">bool isprime[MAXN]; void prime() { memset(isprime,false,sizeof(isprime));//false表示这是素数 for(i=2;i<=MAXN/2+1;i++) { if(!isprime[i])//i是素数 { for(int j=i+i;j<=MAXN;j+=i)//则i的倍数肯定不是素数 isprime[j]=true; } } } 则MAXN内的数全被标记为素数或非素数</span>
- 扩展欧几里德原理:
- 如果所求等式可以化为a*x+b*y=c这种形式就可以用如下代码求方程x,y的解
<span style="font-size:18px;">int kzojld(int a,int b,int &x,int &y)//本题r为a,b最大公约数,但显然我们目的不是要他,而是x,y,所以用引用 { if(b==0) { x=1; y=0; return a; } int temp,r; r=kzojld(b,a%b,x,y); temp=x; x=y; y=temp-a/b*y;//公式直接用 return r; } 注意:此算法求出的x,y并不是方程解,而是x=x*c/gcd(a,b),y=y*c/gcd(a,b) 这时的x,y也不过是一组解 剪切的一段: 至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(a, b)的每个解乘上 c/Gcd(a, b) 即可,但是所得解并不是该方程的所有解,找其所有解的方法如下: 在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,可以 得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),p * a+q * b = c的其他整数解满足: p = p1 + b/Gcd(a, b) * t q = q1 - a/Gcd(a, b) * t(其中t为任意整数) p 、q就是p * a+q * b = c的所有整数解。 此算法还应注意,如果x,y有负数,而题目要求结果mod一个数的话,得处理为正数 if(x<0) { x=k+x%k;//假如题目要mod k }</span>
- 关于欧几里德具体证明:http://baike.baidu.com/view/1478219.htm
- 结论:如果一个数可以表达成num=a^x*b^y*c^z......,则num的约数个数为(a+1)*(b+1)*(c+1)*...
- 结论: p是质数,p<=n,则n!是p的倍数,设p^x是p在n!内的最高幂,则x=[n/p]+[n/p^2]+[n/p^3]+............;而且[n/(ab)]=[[n/a]/b]
数论总结
最新推荐文章于 2022-09-27 08:53:44 发布