挑战性题目DSCT501:大整数因子分解

问题描述

大整数质因子分解。

题解

笑死,数据结构课背包都不讲,却给学生出泼辣肉,我的心里只有感恩。

因为本题的数据范围巨大,传统的O(n)O(\sqrt n)O(n​)的质因数分解已经不适用,需要另外的算法。

首先是质数探测算法——Miller_rabin算法,其基于费马小定理,若p是质数,ap−1≡1(modp)a^{p-1}\equiv1\left(\mod p\right)ap−1≡1(modp)。同时,若ppp为质数,x2≡1(modp)x^2\equiv1\left(\mod p\right)x2≡1(modp)可推出x=1orp−1x=1\ or\ p-1x=1 or p−1。所以,我们要判断一个质数是否是质数时,先套费马小定理判断,如果符合费马小定理,再判断(n−1)/2(n-1)/2(n−1)/2是否满足上述第二个性质,如果对于一个预先设定的质数集合p[](本人使用的集合为2,325,9375,28178,450775,9780504,17952650222, 325, 9375, 28178, 450775, 9780504, 17952650222,325,9375,28178,450775,9780504,1795265022),数字nnn均通过上述检验,则认为其是质数。

之后,再利用大整数因数探测算法Pollar_Rho算法,若正整数nnn至少有一个因子不超过n\sqrt nn​,设它任意一个因子为ppp,若随机生成ppp以内的数,期望O(p)O\left(\sqrt p\right)O(p​)次就可以随机到两个一样的数。

随机生成[1,n][1,n][1,n]的正整数,它们modpmod\ pmod p下可近似看做在[1,p][1,p][1,p]内随机,随机生成两个数a,b(b>a)a,b(b>a)a,b(b>a),若b=a(modp)→p∣(b−a)→gcd(n,b−a)≥pb=a(mod\ p)\rightarrow p|(b-a)\rightarrow gcd(n,\ b-a)\geq pb=a(mod p)→p∣(b−a)→gcd(n, b−a)≥p

那么gcd(n,b−a)gcd\left(n,b-a\right)gcd(n,b−a)必为nnn的一个大于111的因数。令随机数这样生成:a0=C,f(x)=x2+C,ai=f(ai−1)a_0=C,f\left(x\right)=x^2+C,a_i=f\left(a_{i-1}\right)a0​=C,f(x)=x2+C,ai​=f(ai−1​)即跳一步就套用一次f(x)f\left(x\right)f(x)。这样做的好处是:若ax=ay(modp)→ax+1−ay+1=f(ax)−f(ay)=(ax+ay)(ax−ay)=0(modp)a_x=a_y\left(\mod p\right)\rightarrow a_{x+1}-a_{y+1}=f\left(a_x\right)-f\left(a_y\right)=\left(a_x+a_y\right)\left(a_x-a_y\right)=0(\mod p)ax​=ay​(modp)→ax+1​−ay+1​=f(ax​)−f(ay​)=(ax​+ay​)(ax​−ay​)=0(modp) 即任一距离为ddd的随机数modp\mod pmodp相同,所有距离为ddd的随机数modp\mod pmodp都相同,这样只需要检查其中一个即可。

免除记忆化:维护两个数,一个数每次调用两次fff,一个每次调用一次,如果走完了环,最后两个数一定会相遇。同时也枚举了所有距离。

优化:瓶颈在于gcdgcdgcd,可以减少取gcd(n,∣a−b∣)gcd\left(n,\left|a-b\right|\right)gcd(n,∣a−b∣)的次数,将所有的∣a−b∣\left|a-b\right|∣a−b∣乘起来,累计128128128次后再与nnn取gcdgcdgcd(前提是a,ba,ba,b还没有在环上相遇),复杂度约为O(n1/4)O(n^{1/4})O(n1/4)。

代码

感谢我的超人——Rockdu提供的泼辣肉模板,说实话我也没怎么搞懂,以后有缘再学。

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define LL long long
using namespace std;LL n;namespace NT {LL gcd(LL a, LL b) {return b ? gcd(b, a % b) : a;}LL mul(LL a, LL b, LL m) {LL s = a * b - (LL)((long double)a * b / m + 0.5) * m;return s < 0 ? s + m : s;}LL fpow(LL x, LL a, LL m) {LL ans = 1;while(a) {if(a & 1) ans = mul(ans, x, m);x = mul(x, x, m), a >>= 1;}return ans;}
}namespace Miller_Rabin {using namespace NT;LL p[15] = {2, 325, 9375, 28178, 450775, 9780504, 1795265022};int detect(LL n, LL a) {if(n == a) return 1;if(a % n == 0) return 1;LL now = n - 1, lst = 1;if(fpow(a, now, n) != 1) return 0;while(!(now & 1)) {now /= 2;LL p = fpow(a, now, n);if(lst == 1 && p != 1 && p != n - 1)return 0;lst = p;}return 1;}LL MR(LL n) {if(n < 2) return 0;for(int i = 0; i < 7; ++i) {if(!detect(n, p[i])) return 0;}return 1;}
}namespace Pollard_Rho {using namespace NT;using namespace Miller_Rabin;LL f(LL x, LL C, LL p) {return (mul(x, x, p) + C) % p;}LL Rand() {return (rand() << 15) + rand();}LL Randll() {return (Rand() << 31) + Rand();}LL PR(LL n) {if(n == 4) return 2;if(MR(n)) return n;while(1) {LL C = Randll() % (n - 1) + 1;LL s = 0, t = 0;LL acc = 1;do {for(int i = 1; i <= 128; ++i) {t = f(f(t, C, n), C, n);s = f(s, C, n);LL tmp = mul(acc, abs(t - s), n);if(s == t || tmp == 0)break;acc = tmp;}LL d = gcd(n, acc);if(d > 1) return d;} while(s != t);}}typedef pair<LL, int > pii;vector<pii > DCOMP(LL n) {vector<pii > ret;while(n != 1) {LL p = PR(n);while(!MR(p)) p = PR(p);int c = 0;while(n % p == 0) n /= p, ++c;ret.push_back(make_pair(p, c));}return ret;}
}
void out(long long x){if(x>9)out(x/10);putchar(x%10+'0');}
int main(int argc,char* argv[]) {srand(19260817);LL n=atoll(argv[1]);if(n==1)return 0; auto ans = Pollard_Rho::DCOMP(n);out(ans[0].first);ans[0].second--;for(auto i : ans)while(i.second--) putchar('*'),out(i.first);return 0;
}

挑战性题目DSCT501:大整数因子分解相关推荐

  1. 公钥密码系统主要依赖的三种数学难题:1.大整数因子分解问题 2.离散对数问题 (DLP问题) 3. 椭圆曲线上的离散对数问题(ECDLP)

    公钥密码系统主要依赖下面三种数学难题 1.大整数因子分解问题,如 RSA 系统 1.数理 2.流程 2.离散对数问题 (DLP问题) 1.数理: 2.流程:(EIGamal 公钥系统) 3. 椭圆曲线 ...

  2. c语言程序做四则运算还要余数,大整数四则运算 高质量C语言程序.doc

    大整数四则运算 高质量C语言程序 设计题目: 大整数的四则运算 1. 功能简介:编写出实现大整数之间相加,相减,相乘,相除的程序,并输出计算结构. 课程设计要求:采用模块化程序设计 源程序中应有足够的 ...

  3. C语言 大整数运算(加、减、乘)

    题目:大整数计算 背景介绍: 大整数一般指超过十尾的十进制整数,假定不超过五十位.这类大整数在C语言系统中因超界溢出而不能直接表达或计算. 实现方法: 以字符串形式输入.输出和存放大整数,计算时可以将 ...

  4. NOI1.13.47 大整数除法 题解(C++)

    NOI1.13.47 大整数除法 题解(C++) 这题一看题目就知道绝非普通的long long 或 int .这可是高精度呀. 题目 47:大整数除法 总Time Limit: 1000ms Mem ...

  5. 循环相乘取整法C语言,华为OJ机试题目:两个大整数相乘(纯C语言实现两个大整数相乘,两种方法实现大数相乘)...

    题目描述: 输出两个不超过100位的大整数的乘积. 输入: 输入两个大整数,如1234567 123 输出: 输出乘积,如:151851741 样例输入: 1234567 123 样例输出: 1518 ...

  6. 整数判重、大整数Hash

    大整数Hash 总是听高届的大佬说,一个字符串Hash,能搞出大部分的字符串题,Hash真的有那么神吗? 答:是的 近来,参加很多NOIP模拟赛,其中一场设计判断大整数是否存在偷懒了一下,开了一个ma ...

  7. 【PAT甲级 大整数BigInteger】1065 A+B and C (64bit) (20 分) Java 全部AC

    题目 在有些方面,比如大整数的处理,不得不佩服Java,好用没的说,像开挂一样 题解 Java import java.math.BigInteger; import java.util.Scanne ...

  8. LeetCode 1985. 找出数组中的第 K 大整数(排序)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个字符串数组 nums 和一个整数 k . nums 中的每个字符串都表示一个不含前导零的整数. 返回 nums 中表示第 k 大整数的字符串. 注 ...

  9. 信奥中的数学:前缀和与差分、大整数开方技巧

    [算法2-1]前缀和与差分 [算法2-1]前缀和与差分 - 题单 - 洛谷 前缀和与差分 图文并茂 超详细整理(全网最通俗易懂) 前缀和与差分 图文并茂 超详细整理(全网最通俗易懂)_林深不见鹿 的博 ...

  10. 信息学奥赛一本通 1171:大整数的因子 | OpenJudge NOI 1.6 13:大整数的因子

    [题目链接] ybt 1171:大整数的因子 OpenJudge NOI 1.6 13:大整数的因子 [题目考点] 1. 高精度 考察:高精模低精 高精度计算讲解 [解题思路] 先把参与运算的数字当成 ...

最新文章

  1. 2021年春季学期-信号与系统-第六次作业参考答案-第七小题
  2. 20位数字转化成6位不重复码_人力资源管理浅析身份证数字号码编排常识甄别年龄、性别、籍贯…...
  3. html5家谱资源网,免费家谱系统(ASP,Access,CSS,html5)
  4. Asp.Net 数据分页
  5. 对于短信平台呼叫状态机的调查
  6. java Calendar
  7. c++ eos智能合约开发_[EOS智能合约]第二节:用EOS开发一个To-do List小应用
  8. 第14章 任务和特权级保护
  9. linux下安装配置oracle
  10. 微课|中学生可以这样学Python(例8.21):选择法排序
  11. Delphi 的绘图功能[5] - 获取 Canvas 对象
  12. XQuery的contains函数
  13. ulipad双击无反应
  14. Cocos Creator 虚拟摇杆
  15. echart坐标轴添加下划线问题
  16. 阿里巴巴产品经理面试主观题
  17. deepin有线网卡无法连接网络
  18. Android中屏蔽返回键,HOME键以及模拟HOME键返回效果的方法
  19. easyui textbox onblur失效
  20. IE浏览器闪退、自动打开Edge浏览器

热门文章

  1. 207.课程表(力扣leetcode) 博主可答疑该问题
  2. css 绝对定位底部居中,css – 在另一个元素的中心下方水平居中绝对定位元素
  3. android 单手模式开发,单手操作毫无压力 安卓单指缩放技巧
  4. linux内核类型lagency,使用u盘安装linux(manjaro)时Grub报错
  5. 简单的数据库group by后要进行某字段拼接
  6. OAuth2.0认证流程原理
  7. swagger 参数
  8. 图解HTTP---------------------------------------------------3
  9. 微信小程序 this.data与this.setData
  10. 1347 格子游戏 (并查集)