zoukankan      html  css  js  c++  java
  • 【POJ】1811 Prime Test

    http://poj.org/problem?id=1811

    题意:求n最小素因子。(n<=2^54)

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <iostream>
    using namespace std;
    typedef long long ll;
    const ll lim=1e9;
    inline void C(ll &a, ll c) { if(a>=c || a<=-c) a%=c; }
    inline ll mul(ll a, ll b, ll c) { if(a<=lim && b<=lim) return a*b%c; ll x=0; for(; b; b>>=1, C(a+=a, c)) if(b&1) C(x+=a, c); return x; }
    inline ll mpow(ll a, ll b, ll c) { ll x=1; for(; b; b>>=1, a=mul(a, a, c)) if(b&1) x=mul(a, x, c); return x; }
    inline ll rand(ll a, ll b) {
    	static const ll M=1e9+7, g=220703118;
    	static ll now=1998;
    	C(now*=g, M);
    	return a+(now*now)%(b-a+1);
    }
    ll gcd(ll a, ll b) { return b?gcd(b, a%b):a; }
    inline ll iabs(ll a) { return a<0?-a:a; }
    inline ll PR(ll n, ll c) {
    	ll x=rand(0, n-1), y=x, k=2, t;
    	for(int i=2; ; ++i) {
    		x=mul(x, x, n); x+=c; C(x, n);
    		t=gcd(iabs(y-x), n);
    		if(t!=1 && t!=n) return t;
    		if(y==x) return n;
    		if(i==k) y=x, k<<=1;
    	}
    }
    bool check(ll n) {
    	if(n==2 || n==3 || n==5 || n==7 || n==11 || n==13) return 1;
    	if(n<2 || (n&1)==0 || n%3==0 || n%5==0 || n%7==0 || n%11==0 || n%13==0) return 0;
    	ll d=n-1;
    	int cnt=0;
    	while((d&1)==0) d>>=1, ++cnt;
    	for(int i=0; i<20; ++i) {
    		ll a=mpow(rand(2, n-1), d, n);
    		for(int i=0; i<cnt; ++i) { ll t=a; a=mul(a, a, n); if(a==1 && t!=1 && t!=n-1) return 0; }
    		if(a!=1) return 0;
    	}
    	return 1;
    }
    ll f[100], ans;
    int cnt;
    void find(ll n) { //printf("%lld
    ", n);
    	if(check(n)) { 
    		f[++cnt]=n; ans=min(ans, n);
    		return;
    	}
    	ll p=n;
    	while(p==n) p=PR(n, rand(1, n-1));
    	find(p); find(n/p);
    }
    
    int main() {
    	int T; scanf("%d", &T);
    	while(T--) {
    		ll n;
    		scanf("%lld", &n);
    		cnt=0; ans=n;
    		find(n);
    		if(cnt==1) puts("Prime");
    		else printf("%lld
    ", ans);
    	}
    
    	return 0;
    }
    

      

    学习了下Pollard-Rho算法= =复杂度期望为$O(n^{1/4})$

    具体不说看算导= =

    大概就是用$x=x^2+c pmod{n}$然后判$(y-x, n)$是否=1。其中$y$是第$2^k$个$x$。然后找到一个约数后递归这个约数和n/约数。($c$和初始的$x$随机= =

    然后如果碰到环退出就行了= =(一开始不知道为啥被卡了= =原来乘法爆掉了QAQ写个快速乘啊  !!!

  • 相关阅读:
    使用numpy生成二维正态分布
    %matplotlib inline的含义
    The following packages will be SUPERCEDED by a higher-priority channel是什么意思?
    conda命令详解
    软件包,API,SDK的区别
    IP组网实验(使用Cisco Packet Tracer路由器模拟软件)
    MAC地址表、ARP缓存表、路由表及交换机、路由器基本原理
    K'ed by TNT team是什么意思?
    使用Applescript、Automator和AfredWorkflow实现流式工作
    Redux源码分析之createStore
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4355388.html
Copyright © 2011-2022 走看看