Processing math: 100%

HDU3864 D_num

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

 

 

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

 

 

题目链接:HDU3864

正解:Pollardrho

解题报告:

  Pollardrho算法模板题。

  考虑对于一个数n,我们有一个n以内的数对(x,y),若gcd(xy,n)!=1,那么显然找到了一个n的因数g,递归往下做下去,分别分解质因子即可。

  这个做法的期望次数会很少,可以想想生日悖论。

  具体做法就是构造一个序列xixi=x2i1+cx0c均为n以内不为0的随机数,我们就这样做下去,y就取2的次幂,x单增,直到找到为止。

  发现有可能如果x0c不好的话可能无解(出现环),需要多随几次,环的判断就是xy某次突然相等了。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//It is made by ljh2000
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <string>
#include <complex>
#include <bitset>
using namespace std;
typedef long long LL;
typedef long double LB;
typedef complex<double> C;
const double pi = acos(-1);
LL n;
vector<LL>w;
 
inline int getint(){
    int w=0,q=0; char c=getchar(); while((c<'0'||c>'9') && c!='-') c=getchar();
    if(c=='-') q=1,c=getchar(); while (c>='0'&&c<='9') w=w*10+c-'0',c=getchar(); return q?-w:w;
}
 
inline LL gcd(LL x,LL y){ if(y==0) return x; return gcd(y,x%y); }
 
inline LL mul(LL x,LL y,LL mod){
    LL r=0;
    while(y>0) {
        if(y&1) r+=x,r%=mod;
        x+=x; x%=mod;
        y>>=1;
    }
    return r;
}
 
inline LL fast_pow(LL x,LL y,LL mod){
    LL r=1;
    while(y>0) {
        if(y&1) r=mul(r,x,mod);
        x=mul(x,x,mod);
        y>>=1;
    }
    return r;
}
 
inline int MillerRabin(LL n){
    if(n==1) return 0; if(n==2) return 1; if(!(n&1)) return 0;
    LL aa=n-1,k=0,bb,lin,cc; while(!(aa&1)) aa>>=1,k++; int T=5;
    while(T--) {
        bb=rand()%(n-1)+1; cc=fast_pow(bb,aa,n);
        for(LL i=1;i<=k;i++) {
            lin=mul(cc,cc,n);
            if(lin==1 && cc!=1 && cc!=n-1) return 0;
            cc=lin;
        }
        if(cc!=1) return 0;
    }
    return 1;
}
 
inline LL nex(LL x,LL c,LL n){
    return (mul(x,x,n)+c)%n;
}
 
inline void pollardrho(LL n){
    while(!(n&1)) n>>=1,w.push_back(2); if(n==1) return ;
    if(MillerRabin(n)) { w.push_back(n); return ; }
    LL x=rand()%(n-1)+1,y=x,c=rand()%(n-1)+1,g;
    for(LL i=1,j=1;;i++) {
        x=nex(x,c,n);
        g=gcd(abs(x-y),n);
        if(x==y) x=rand()%(n-1)+1,y=x,c=rand()%(n-1)+1,i=0,j=1;
        if(g>1 && g<n) break;
        if(i==j) j<<=1,y=x;
    }
    pollardrho(g); pollardrho(n/g);
}
  
inline void work(){
    srand(time(NULL));
    while(scanf("%lld",&n)!=EOF) {
        if(n==1){ cout<<"is not a D_num"<<endl; continue; }
        w.clear();
        pollardrho(n);
        int t=w.size();
        if(t!=2&&t!=3){ cout<<"is not a D_num"<<endl; continue; } 
 
        sort(w.begin(),w.end()); 
 
        if(t==2) { 
            if(w[0]!=w[1]) cout<<w[0]<<" "<<w[1]<<" "<<n<<endl; 
            else cout<<"is not a D_num"<<endl; 
        
        else
            if(w[0]==w[1] && w[1]==w[2]) cout<<w[0]<<" "<<w[0]*w[0]<<" "<<n<<endl; 
            else cout<<"is not a D_num"<<endl; 
        
    }
}
  
int main()
{  
    work();
    return 0;
}
//有志者,事竟成,破釜沉舟,百二秦关终属楚;苦心人,天不负,卧薪尝胆,三千越甲可吞吴。

  

posted @   ljh_2000  阅读(145)  评论(0编辑  收藏  举报
编辑推荐:
· 开发中对象命名的一点思考
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
阅读排行:
· 本地部署 DeepSeek:小白也能轻松搞定!
· 基于DeepSeek R1 满血版大模型的个人知识库,回答都源自对你专属文件的深度学习。
· 在缓慢中沉淀,在挑战中重生!2024个人总结!
· 大人,时代变了! 赶快把自有业务的本地AI“模型”训练起来!
· Tinyfox 简易教程-1:Hello World!
点击右上角即可分享
微信分享提示