1. 程式人生 > >【模板】Pollard-Rho分解質因數

【模板】Pollard-Rho分解質因數

參考題目:BZOJ3667


解析:

板子題解析看心情更新

BB:在這份板子裡面你看到的所有卡常痕跡都是為了那個毒瘤資料的洛谷版題(雖然最後還是沒有過。。。)


UPD:

終於找到洛谷上面過不了的原因了。
新的能過的程式碼放在最下面,大家可以自己找一下不同,主要是實現的地方比較關鍵。


程式碼(洛谷未過):

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc get_char
#define pc put_char
#define puts put_s #define cs const namespace IO{ cs int Rlen=1<<18|1; char buf[Rlen],*p1=buf,*p2=buf; char obuf[Rlen],*p3=obuf; inline char get_char(){ return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++; } inline ll getint
(){ re ll num; re char c; while(!isdigit(c=gc()));num=c^48; while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48); return num; } inline void put_char(char c){ *p3++=c; if(p3==obuf+Rlen)fwrite(obuf,1,Rlen,stdout),p3=obuf; }
inline void put_s(cs char *s){ for(int re i=0;s[i];++i)pc(s[i]);pc('\n'); } inline void outint(ll a){ static char ch[23]; if(a==0)pc('0'); while(a)ch[++ch[0]]=a-a/10*10,a/=10; while(ch[0])pc(ch[ch[0]--]^48);pc('\n'); } inline void FLUSH(){ if(p3==obuf)return ; fwrite(obuf,1,p3-obuf,stdout); p3=obuf; } } using namespace IO; inline ll mul(ll a,ll b,ll mod){ return (a*b-(ll)((long double)a/mod*b)*mod+mod)%mod; } inline ll quickpow(ll a,ll b,ll mod){ re ll ans=1; for(;b;b>>=1,a=mul(a,a,mod))if(b&1)ans=mul(ans,a,mod); return ans; } cs int P=1007; bitset<P> mark; int prime[P],pcnt; int maxpri[P]; inline void linear_sieves(int len=P-7){ mark[1]=true; for(int re i=2;i<=len;++i){ if(!mark[i])prime[++pcnt]=i,maxpri[i]=i; for(int re j=1;j<=pcnt&&i*prime[j]<=len;++j){ mark[i*prime[j]]=true; maxpri[i*prime[j]]=maxpri[i]; if(i==i/prime[j]*prime[j])break; } } } inline bool isprime(ll x){ if(x<=P-7)return !mark[x]; if(!(x&1)||(x%3==0)||(x%5==0)||(x%7)==0||(x%61==0)||(x%24251)==0)return false; ll t=x-1,s=0; while(!(t&1))t>>=1,++s; for(int re i=1;i<=5;++i){ ll p=prime[rand()%pcnt+1]%x; ll num=quickpow(p,t,x),pre=num; if(x%p==0)return false; for(int re j=0;j<s;++j){ num=mul(num,num,x); if(num==1&&pre!=1&&pre!=x-1)return false; pre=num; } if(num!=1)return false; } return true; } inline ll gcd(ll a,ll b){ if(!a||!b)return a+b; re int t=__builtin_ctzll(a|b); a>>=__builtin_ctzll(a); while(b){ b>>=__builtin_ctzll(b); if(a>b)a^=b,b^=a,a^=b; b-=a; } return a<<t; } ll ans; inline ll Pollard_Rho(ll x){ if(x%2==0)return 2; if(x%3==0)return 3; if(x%5==0)return 5; if(x%7==0)return 7; if(x%61==0)return 61; if(x%24251==0)return 24251; re ll i=1,k=2,n=rand()%(x-1)+1,m=n,c=rand()%(x-1)+1; while(true){ ++i; n=(mul(n,n,x)+c)%x; re ll p=gcd((m-n+x)%x,x); if(p!=1&&p!=x)return p; if(m==n)return x; if(i==k)k<<=1,m=n; } } inline void sieves(ll x){ if(x==1)return ;if(x<=ans)return ; if(isprime(x))return (void)(ans=max(ans,x)); if(x<=P-4)return (void)(ans=max(ans,(ll)maxpri[x])); re ll p=x; while(p>=x)p=Pollard_Rho(p); sieves(p); while(x%p==0)x/=p; sieves(x); } int T; signed main(){ srand(time(0)); linear_sieves(); T=getint(); while(T--){ ll n=getint(); if(n<=P-7)mark[n]?outint(maxpri[n]):puts("Prime"); else { ans=0; sieves(n); if(ans==n)puts("Prime"); else outint(ans); } } FLUSH(); return 0; }

程式碼:(洛谷已過)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc get_char
#define pc put_char
#define puts put_s
#define cs const

namespace IO{
    cs int Rlen=1<<18|1;
    char buf[Rlen],*p1=buf,*p2=buf;
    char obuf[Rlen],*p3=obuf;
    
    inline char get_char(){
        return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
    }
    
    inline ll getint(){
        re ll num;
        re char c;
        while(!isdigit(c=gc()));num=c^48;
        while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
        return num;
    }
    
    inline void put_char(char c){
        *p3++=c;
        if(p3==obuf+Rlen)fwrite(obuf,1,Rlen,stdout),p3=obuf;
    }
    
    inline void put_s(cs char *s){
        for(int re i=0;s[i];++i)pc(s[i]);pc('\n');
    }
    
    inline void outint(ll a){
        static char ch[23];
        if(a==0)pc('0');
        while(a)ch[++ch[0]]=a-a/10*10,a/=10;
        while(ch[0])pc(ch[ch[0]--]^48);pc('\n');
    }
    
    inline void FLUSH(){
        if(p3==obuf)return ;
        fwrite(obuf,1,p3-obuf,stdout);
        p3=obuf;
    }
}
using namespace IO;

inline ll mul(ll a,ll b,ll mod){
    return (a*b-(ll)((long double)a/mod*b)*mod+mod)%mod;
}

inline ll quickpow(ll a,ll b,ll mod){
    re ll ans=1;
    for(;b;b>>=1,a=mul(a,a,mod))if(b&1)ans=mul(ans,a,mod);
    return ans;
}

cs int P=1007;
bitset<P> mark;
int prime[P],pcnt;
int maxpri[P];
inline void linear_sieves(int len=P-7){
    mark[1]=true;
    for(int re i=2;i<=len;++i){
        if(!mark[i])prime[++pcnt]=i,maxpri[i]=i;
        for(int re j=1;j<=pcnt&&i*prime[j]<=len;++j){
            mark[i*prime[j]]=true;
            maxpri[i*prime[j]]=maxpri[i];
            if(i==i/prime[j]*prime[j])break;
        }
    }
}

inline bool isprime(ll x){
    if(x<=P-7)return !mark[x];
    if(!(x&1)||(x%3==0)||(x%5==0)||(x%7)==0||(x%61==0)||(x%24251)==0)return false;
    ll t=x-1,s=0;
    while(!(t&1))t>>=1,++s;
    for(int re i=1;i<=5;++i){
    	ll p=prime[rand()
            
           

相關推薦

模板Pollard-Rho分解質因數

參考題目:BZOJ3667 解析: 板子題解析看心情更新 BB:在這份板子裡面你看到的所有卡常痕跡都是為了那個毒瘤資料的洛谷版題(雖然最後還是沒有過。。。) UPD: 終於找到洛谷上面過不了的原因了。 新的能過的程式碼放在最下面,大家可以自己找一下不同,主

luogu P4718 模板Pollard-Rho演算法(貼程式碼)

嘟嘟嘟 從標題中能看出來,我只是想貼一個程式碼。 先扯一會兒。 前幾天模擬考到了這東西,今天有空就學了一下。 到網上找資料,發現前置技能是miller-rabin篩法,於是我還得先學這麼個東西。 學miller-rabin的話不得不推薦這兩篇文章: 大數質因解:淺談Miller-Rabin和Pollard

模板質因數分解

space \n int return name puts continue con ont 對於 N 的質因數分解,直接從 2 開始遍歷到 \(\sqrt(n)\) 即可,最後如果 N>1,則多計入一個因子即可。 代碼如下 #include <bits/std

Miller-rabin素性測試與pollard-rho快速質因數分解

~~~~ Miller-Rabin 可以在O(log n)的時間內檢測一個數是否為質數。 理論上是一個概率演算法,但在一定範圍以內的數經過驗證全部可以判出來。 所以OI範圍內可以視作是一個確定演算法。 費馬小定理 若p是質數,且a<pa

P3372 模板線段樹 1

load color 求和 整數 數字 amp article http cst 題目描述 如題,已知一個數列,你需要進行下面兩種操作: 1.將某區間每一個數加上x 2.求出某區間每一個數的和 輸入輸出格式 輸入格式: 第一行包含兩個整數N、M,分別表示該數

P3383 模板線性篩素數

... right else cst pre left 數據 ret col 題目描述 如題,給定一個範圍N,你需要處理M個某數字是否為質數的詢問(每個數字均在範圍1-N內) 輸入輸出格式 輸入格式: 第一行包含兩個正整數N、M,分別表示查詢的範圍和查詢

P3371 模板單源最短路徑

logs alt front 最短路徑 ios num return struct 有向圖 題目描述 如題,給出一個有向圖,請輸出從某一點出發到所有點的最短路徑長度。 輸入輸出格式 輸入格式: 第一行包含三個整數N、M、S,分別表示點的個數、有向邊的個數

P3366 模板最小生成樹

解釋 truct 技術 題目 bre != union 100% 個數 題目描述 如題,給出一個無向圖,求出最小生成樹,如果該圖不連通,則輸出orz 輸入輸出格式 輸入格式: 第一行包含兩個整數N、M,表示該圖共有N個結點和M條無向邊。(N<=5000,M

[洛谷3373]模板線段樹 2

兩個 cstring tchar int() 維護 string max nbsp 線段 思路: 線段樹。同時維護兩個 lazy tag ,一個維護乘,一個維護加。根據加法結合律,可以得出:當同一個結點進行兩次加操作時,新的標記等於兩次標記之和。根據乘法結合律,可以得出:

模板負環(spfa)

sizeof 貪心 com image 一行 clas 存在 cst -m 洛谷——P3385 【模板】負環 題目描述 暴力枚舉/SPFA/Bellman-ford/奇怪的貪心/超神搜索 輸入輸出格式 輸入格式: 第一行一個正整數T表

二分圖匹配 模板

print front space namespace spl ide ons urn sca 1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio&g

洛谷—— P3386 模板二分圖匹配

blank lan print 一個 dfs com 二分 i++ bool https://www.luogu.org/problem/show?pid=3386 題目背景 二分圖 題目描述 給定一個二分圖,結點個數分別為n,m,邊數為e,求二分圖最大匹配數 輸

洛谷——P3370 模板字符串哈希

大小寫 100% max algorithm () problem pri node pan 題目描述 如題,給定N個字符串(第i個字符串長度為Mi,字符串內包含數字、大小寫字母,大小寫敏感),請求出N個字符串中共有多少個不同的字符串。 友情提醒:如果真的想好好練習哈希

Luogu P3375 模板KMP字符串匹配

ogr oss tel 詳解 最長 arch tro long abc P3375 【模板】KMP字符串匹配 題目描述 如題,給出兩個字符串s1和s2,其中s2為s1的子串,求出s2在s1中所有出現的位置。 為了減少騙分的情況,接下來還要輸出子串的前綴數組

三分法(洛谷3382 模板三分法)

printf log 含義 三分 tps ans 區間 bits int 如題,給出一個N次函數,保證在範圍[l,r]內存在一點x,使得[l,x]上單調增,[x,r]上單調減。試求出x的值。 輸入格式: 第一行一次包含一個正整數N和兩個實數l、r,含義如題目描述所示。

[洛谷3366]模板最小生成樹

fine nds first 最小 fin print kruskal += sca 思路:Kruskal 1 #include<cstdio> 2 #include<utility> 3 #include<algorithm&

模板左偏樹(可並堆)

inline 限制 需要 表示 開始 cnblogs -a 刪除 ont 題目描述 如題,一開始有N個小根堆,每個堆包含且僅包含一個數。接下來需要支持兩種操作: 操作1: 1 x y 將第x個數和第y個數所在的小根堆合並(若第x或第y個數已經被刪除或第x和第y個數在

模板字符串哈希

ret blog return cst unsigned urn amp hash color OJ題號:洛谷3370 思路:BKDR 1 #include<cstdio> 2 #include<vector> 3 #include

P3373 模板線段樹 2 區間求和 區間乘 區間加

std 數列 cst printf int img ostream string uil 題目描述 如題,已知一個數列,你需要進行下面兩種操作: 1.將某區間每一個數加上x 2.將某區間每一個數乘上x 3.求出某區間每一個數的和 輸入輸出格式 輸入格

洛谷P3385 模板負環 DFS-SPFA 判負環 圖論

string inf scan space can 清空 span %d pre 洛谷P3385 【模板】負環 圖論 今天get了 一個 DFS-SPFA 判負環的方法 一般的 BFS-SPFA 判負環 一般就是 不停地做,如果某點第 n+1次加入隊列中,那麽說明這個圖存在