简单数学(关于素数判断和因数分解)
来源:互联网 发布:磁盘格式化数据恢复 编辑:程序博客网 时间:2024/05/22 03:48
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int P=1e9+7,M=1e6+5;ll exgcd(ll a,ll b,ll &x,ll &y){ if(!b){x=1;y=0;return a;} ll t=x-(a/b)*y; return exgcd(b,a%b,y,t);}inline ll gcd(ll x,ll y){ while(y)y^= x^= y ^=x %=y; return x;}//快速幂inline int fast(int b,int n){ ll a=b,ans=1; while(n){ if(n&1)ans=(ans*a)%P; a=1ll*a*a%P; n>>=1; }}//快速乘 inline int Pre(ll x,ll n,ll mod){ int res=0; x%=p; while(n){ if(n&1)res=x+res%mod; x=(x+x)%p; n>>=1; }return res;}//我们要保证每个数只被它最小的质因子标记一次。int check[M],prime[M],num,ans[M];inline void init(int n){ memset(check,0,sizeof(check)); for(int i=2;i<=n;i++){ if(!check[i])prime[++num]=i; for(int j=1;j<=num;j++){ if(prime[j]*i>n)break; //记录最小质因子 check[i*prime[j]]=prime[j]; if(i%prime[j]==0)break; } }}//1e9因数分解void solve_1e9_div(int n){ while(check[n]){ ans[++num]=check[n]; n/=check[n]; }ans[++num]=n; }//对于1e18的质数判定//利用费马小定理//对于互质的整数x和质数p,//x^p-1=1(mod p)//但是它有一定的局限性 如341//首先判掉2和偶数。//我们可以考虑这个式子x^2≡1 (mod n)//x^2-1 ≡0 (mod n)//(x-1) (x+1) = kn//由于0≤x <n如果n是一个质数,显然只能(x-1)|n或者(x+1)|n,也就是x=1,n-1。//所以如果有一个x不是这两个数的解,则n一定不是质数。//对于10^18以内的数,x取前9个质数就可以准确无误的判断了。bool is_inv(int x,int p){ ll a=x,u=p-1,res=1; while(u){ ll nw=res; ll nx=nw*nw%p; if(nx==1&&nw!=1&&nw!=p-1)return 0; //x^2-1 ≡0 (mod n) //(x-1) (x+1) = kn //x=1,n-1; if(u&1)res=res*a%p; a=a*a%p; u>>=1; } return res==1;//x^(p-1)%p==1}bool miller_rabin(ll n){ if(n==2)return 1; if(n<2||n%2==0)return 0; //非常大的优化 for(int i=1;prime[i]<n&&i<=20;i++){ if(!is_inv(prime[i],n))return 0; }return 1;}//所以如果我们在(mod m)的意义下,随机生成一个序列。//当序列长度为√m的时候,就有两个数相同。(生日悖论)//如果我们要分解n,对于n的最小质因子,假设为p,那么在√p步之内,很可能找到两个数在(mod p)下同余。//如果我们找到了两个数x_1和x_2,他们在模p下同余,却在模n下不同余,那么我们求 gcd(n,x_1-x_2),就找到一个质因子。map<ll,int>res;map<ll,int>::iterator it;ll pollard_rho(ll n,ll c){ ll x,y,d,i=1,k=2; x=rand()%n+1; y=x; while(1){ i++; x=(Pre(x,x,n)+c)%n; //x[i+1]=x[i]*x[i]+c;来充当随机数组 d=gcd(y-x,n); if(1<d&&d<n)return d;//找到了 if(y==x)return n;//没有用 if(i==k)y=x,k<<=1;//找到第2^k项为 y }}void div_(ll n,ll c){ if(n==1)return; if(miller_rabin(n)){ res[n]++; return; } ll p=n; while(p==n)p=pollard_rho(p,c--); div_(p,c); div_(n/p,c);}void solve_1e18_div(ll n){ init(1e6); srand((int)time(0)); res.clear(); div_(n,(int)rand()+1e9); if(res.empty())printf("%lld\n",n); for(it= res.begin(); it!= res.end();){ printf( "%lld^%d",it->first,it->second); if((++it) != res.end())printf( " * " ); } }
3 0
- 简单数学(关于素数判断和因数分解)
- 大素数判断和分解
- 【原】求解一个数的所有素数因数(因数分解)
- 判断素数.水仙花数(hash实现).分解因数.猴子吃桃
- 数学初步之素因数分解(快速)
- 关于因数分解的计算(淘宝一面试题)
- poj 2429 GCD & LCM Inverse miller_rabin素数判定和pollard_rho因数分解
- poj1811(miller_robin和pollard分解因数的随机性算法)
- 判断是否为素数 + 分解质因数(利用了Miller_Rabin和素数筛选法)
- miller_rabin素数判断和pollard_rho的素数因子分解算法
- 分解因数
- 因数分解
- 分解因数
- 因数分解
- 因数分解
- 分解因数
- Miller Robin素数测试与Pollcard Rho因数分解
- POJ1811-Prime Test-素数测试+Pollard rho因数分解
- Tomcat服务器的安装和启动
- 数据机构1
- 《Java高并发程序设计》学习 --5.3 并行模式之生产者-消费者模式
- TCP/IP 如何断开连接
- CSS样式预设
- 简单数学(关于素数判断和因数分解)
- android-webView与H5的调用
- A股-入门-教你如何克服股市赔钱的心理短板
- cdn
- Castle Windsor 学习-----Installer的几种安装方式
- SED 简明教程
- android-wifi
- LeetCode:328. Odd Even Linked List
- 快速傅里叶变换