POJ2429 GCD & LCM Inverse
2015-08-11 21:29
323 查看
要点:大数质因子分解(Pollard_rho就可以解决)
题目链接:http://poj.org/problem?id=2429
代码好长呀!
题目链接:http://poj.org/problem?id=2429
代码好长呀!
#include<stdio.h> #include<iostream> #include<string> #include<string.h> #include<stdlib.h> #include<math.h> #include<algorithm> using namespace std; #define ll long long #define nn 110 #define S 20 ll pr[nn],f[nn]; int tol,k; ll ans; ll mult_mod(ll a,ll b,ll c)//(a*b)%c { a%=c; b%=c; ll ret=0; while(b) { if(b&1) { ret+=a; ret%=c; } a<<=1; if(a>=c) a%=c; b>>=1; } return ret; } ll pow_mod(ll x,ll n,ll mod)//取模x^n%c { if(n==1) return x%mod; x%=mod; ll tmp=x; ll ret=1; while(n) { if(n&1) ret=mult_mod(ret,tmp,mod); tmp=mult_mod(tmp,tmp,mod); n>>=1; } return ret; } bool check(ll a,ll n,ll x,ll t) { ll ret=pow_mod(a,x,n); ll last=ret; for(int i=1;i<=t;i++) { ret=mult_mod(ret,ret,n); if(ret==1&& last!=n-1 && last!=1) return true; last=ret; } if(ret!=1) return true; return false; } bool miller_rabin(ll n)//判断n是否为素数 { if(n<2) return false; if(n==2) return true; if((n&1)==0) return false; ll x=n-1; ll t=0; while((x&1)==0) { x>>=1; t++; } for(int i=0;i<S;i++) { ll a=rand()%(n-1)+1; if(check(a,n,x,t)) return false; } return true; } ll gcd(ll a,ll b) { if(a==0) return 1; if(a<0) return gcd(-a,b); while(b) { ll t=a%b; a=b; b=t; } return a; } ll pollard_rho(ll x,ll c)//分解出一个因子来 { ll i=1,k=2; ll x0=rand()%x; ll y=x0; while(1) { i++; x0=(mult_mod(x0,x0,x)+c)%x; ll d=gcd(y-x0,x); if(d!=1&&d!=x) return d; if(y==x0) return x; if(i==k) { y=x0; k+=k; } } } void findfac(ll n) { if(miller_rabin(n)) { pr[tol++]=n; return; } ll p=n; while(p>=n) p=pollard_rho(p,rand()%(n-1)+1); findfac(p); findfac(n/p); } void findx(ll i,ll x,ll q) { if(i==k) return ; if(x>ans && x<=q) ans=x; findx(i+1,x,q); x*=f[i]; if(x>ans&& x<=q) ans=x; findx(i+1,x,q); } int main() { ll a,b,m; while(~scanf("%lld%lld",&a,&b)) { if(a==b) { printf("%lld %lld\n",a,b); continue; } ll n=b/a; tol=0; findfac(n); sort(pr,pr+tol); k=1; f[0]=1; for(int i=1;i<tol;i++) { if(pr[i]==pr[i-1]) f[k-1]++; else { pr[k++]=pr[i]; f[k-1]=1; } } // for(int i=0;i<k;i++) // printf("%lld %lld\n",pr[i],f[i]); // printf("\n"); ll j,m; for(int i=0;i<k;i++){//将相同素因子作为一个整体处理 for(j=1,m=pr[i];j<f[i];j++) m*=pr[i]; f[i]=m; } // for(int i=0;i<k;i++) // printf("%lld %lld\n",pr[i],f[i]); // printf("\n"); ll q=(ll)sqrt(n*1.0); ans=1; findx(0,1,q); // printf("ans==%lld\n",ans); printf("%lld %lld\n",ans*a,n/ans*a); } return 0; }
相关文章推荐
- 借贷宝有多少人看得懂?借贷宝系统崩溃分析
- K - Leapin' Lizards - HDU 2732(最大流)
- 最大公共字串LCS问题(阿里巴巴)
- java实现邮箱发送功能
- 用RAID0 安装Ubuntu Server
- java复习-类和对象(二)
- 欢迎使用CSDN-markdown编辑器
- NOIP2013 货车运输(最大生成树+LCA)
- 链表插入排序
- HDU1272 小希的迷宫
- SQL遍历文件夹 / 文件,返回文件夹列表信息
- Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解
- Java读写txt文件中文乱码问题的解决
- C语言第二天
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 还在为工作发愁?学JavaScript吧
- 我所理解的service
- android:installLocation="preferExternal"的意义
- atitit.js的 字符串内容 转义  js处理html
- java设计模式之观察者模式