裴蜀定理
两个数之间:
假设两个数a,b,gcd(a,b)=c
1>证ax+by=d,则c|d,因为c|a&&c|b,所以c|(ax+by),所以c|d.
2>证对于k取任何整数值,总存在x,y使得ax+by=kc,根据扩展欧几里得可以得到这个结论。
3>证根据扩展欧几里得得到的基本解,x1,y1,那么解的范围是x1-kb/c,y1+ka/c,k取任意的整数:首先取另一组解,x2,y2,那么 (y2-y1)/(x1-x2)=(a/c)/(b/c),所以y2-y1=k(a/c),x1-x2=k(b/c),所以其它解与基本解之间满足这个关系,下面证,只要满足这个关系,就是解,只要把x1-kb/c,y1+ka/c带进去就可以证明。
可推广版:
假设两个数a,b,gcd(a,b)=c,假设ax+by的取值范围内最小的正整数是s,即存在x,y使得ax+by=s,下证s==c
设q=|_a/s_|,那么a%s=a-qs=a-q(ax+by)=a(1-qx)-by,可得a%s同样是a和b的一个线性组合,又因为0<=a%s<s,所以a%s只能等于0,所以s|a,同理s|b,所以s|c,s<=c,由上面1>可得,c|s,所以c<=s,所以c==s.
分解一个数n大概只需要sqrt(n)左右的时间:
当遍历完sart(n)时,假设剩下的数是x,它必然是一个质数,证:
假设它不是一个质数,则,则它的素因子必然都大于sqrt(n),而这是不现实的,所以可证。
参考代码:http://www.cnblogs.com/shihuajie/archive/2013/03/25/2980709.html
package a;
import java.math.BigInteger;
import java.util.Scanner;
public class Ha{
static long n,m;
static Scanner in=new Scanner(System.in);
static BigInteger ans=new BigInteger("0");
static long[] prime=new long[20];
static public BigInteger km(long x,long y){//本来是把y改成BigInteger,结果超时,改回long,就wr了,说明BigInteger虽然好用,但是不能多用,就好像肉一样,好吃,但是不能多吃。还有现在总算知道为什么编译器不出结果了,不出结果但能继续输入,所以以为是编译器坏了,结果是tle
BigInteger tempans=new BigInteger("1");
BigInteger tempx=new BigInteger(String.valueOf(x));
while(y!=0){
if(y%2!=0){
tempans=tempans.multiply(tempx);
}
tempx=tempx.multiply(tempx);
y=y/2;
}
return tempans;
}
static public void main(String args[]){
n=in.nextLong();
m=in.nextLong();
long tempm=m;
int loca=0;
ans=ans.add(km(m,n));
for(long i=2;i*i<=m;i++){//因为这里m出现在判断条件中,所以m在循环中不能变,这里应该从2开始,否则会陷入死循环
if(tempm%i==0){
prime[loca++]=i;
ans=ans.subtract(km(m/i,n));//把这个放外面了,所以wr了,再次强调,所以写代码时要想意义。
}
while(tempm%i==0){
tempm=tempm/i;
}
}
if(tempm!=1){
prime[loca++]=tempm;
ans=ans.subtract(km(m/tempm,n));
}
//System.out.println(loca);
//System.out.println(ans);
long end=(long)1<<loca;
for(long i=1;i<end;i++){//因为容斥原理中是任意一个,任意两个,任意三个……,所以应该从1开始,而不是从0开始
int cou=0;
long mul=1;
long tempi=i;
for(int j=0;j<loca;j++){
if(tempi%2!=0){
cou++;
mul=mul*prime[j];
}
tempi=tempi/2;
}
if(cou==1){//这个忘了加
continue;
}
if(cou%2==0){
ans=ans.add(km(m/mul,n));
}
else{
ans=ans.subtract(km(m/mul,n));
}
}
System.out.println(ans);
return;
}
}