poj1811,权当模板~
#include <stdio.h> #include <string.h> #include <stdlib.h> #define swap(a,b) do{a=a^b;b=a^b;a=a^b;}while(0) typedef long long LL; LL gcd(LL a,LL b) { while(b){swap(a,b);b=b%a;} return a>0?a:-a; } LL mod_mult(LL a,LL b,LL mo)//ret:a*b%mo { LL ret; a%=mo; for(ret=0;b;a=(a<<1)%mo,b>>=1) if(b&1) ret=(ret+a)%mo; return ret; } LL mod_exp(LL a,LL b,LL mo)//ret:a^b%mo { LL ret=1,temp=a%mo; for(;b;b>>=1,temp=mod_mult(temp,temp,mo)) if(b&1) ret=mod_mult(ret,temp,mo); return ret; } LL pollard_rho(LL n,int c) { LL x,y,d,i=1,k=2; x=rand()%(n-1)+1; y=x; while(1) { i++; x=(mod_mult(x,x,n)+c)%n; d=gcd(y-x,n); if(d>1&&d<n)return d; if(x==y)return n; if(i==k)y=x,k<<=1; //if(k>1<<11)return n; } } int miller_rabin(LL n,int time) { if (n==2||n==3||n==5||n==7)return 1; if (n<2||!(n&1))return 0; int i,j,t=0; LL a,x,y,u=n-1; while((u&1)==0) t++,u>>=1; for(i=0;i<time;i++) { a=rand()%(n-1)+1; x=mod_exp(a,u,n); for(j=0;j<t;j++) { y=mod_mult(x,x,n); if (y==1&&x!=1&&x!=n-1) return 0; x=y; } if (x!=1) return 0; } return 1; } LL min; void fuck(LL i) { LL x; if(miller_rabin(i,8)){if(i<min)min=i;/*printf(" %lld ",i);*/return;} do{x=pollard_rho(i,rand()%15+2);}while((x==1||x==i)); fuck(x); fuck(i/x); } int main() { LL i;int t; scanf("%d",&t); while(t--){ scanf("%lld",&i); min=i; fuck(i); if(i!=min)printf("%lld\n",min); else printf("Prime\n");} return 0; }
数论相关算法(未完)
辗转相除法最大公约数:
//要求a,b不同时为零 int gcd(int a,int b) { if(!b)return a; else return gcd(b,a%b); }
利用最大公约数求最小公倍数:
int lcm(int a,int b) { if(!(a*b))return 0; else return a*b/gcd(a,b); }
求:
int modExp(int a,int b,int n) { int t=1,y=(a%n+n)%n; while(b) { if(b%2==1)t=t*y%n; y=y*y%n; b/=2; } return t; }
扩展的Euclid算法:
//返回a,b的最大公约数d,并使ax+by=d int ExtEuclid(int a,int b,int *x,int *y) { int d,tmp; if(b==0) { *x=1; *y=0; return a; } d=ExtEuclid(b,a%b,x,y); tmp=*x; *x=*y; *y=tmp-a/b*(*x); return d; }
解线性同余方程:
//返回最小的x...通解是X=x(mod n/d) int modularLinerEquation(int a,int b,int n) { int x,y,d; d=ExtEuclid(a,n,&x,&y); if(b%d!=0)return -1; // no solution x=b/d*x; x=(x%(n/d)+(n/d))%(n/d); return x; }
用中国剩余定理解同余方程组:
//用中国剩余定理解线性同与方程组$a\equiv b_i(\mod m_i)$ int solModularEquations(int b[],int m[],int z) { int M=1,i,y,result=0; for(i=0;i<z;i++)M*=m[i]; for(i=0;i<z;i++) { y=modularLinerEquation(M/m[i],1,m[i]); result=(result+y*b[i]*M/m[i])%M; } return result; }
Miller-Rabin测试:
//Miller-Rabin素性测试 //令大奇数$n=2^lm+1$,其中l非负整数,m为正奇数. //若$b^m\equiv 1(\mod n)$或者$b^{2^jm}\equiv -1(\mod n)$ ,0<=j<=l-1 //则称n通过以b为基的miller-rabin测试 int passMillerRabinTest(int n) { int l,m; m=n-1; l=0; while(m%2==0) { l++; m/=2; } b=rand()%(n-1)+1; if(modExp(b,m,n)==1)return 1; int i,k; k=m; for(i=0;i<l;i++) { if(modExp(b,k,n)==n-1)return 1; k*=2; } return 0; }