E.Multiply Pollard_rho质因数分解

2024-01-26 11:58

本文主要是介绍E.Multiply Pollard_rho质因数分解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2019 icpc xuzhou
思路很简单, 但是这个Pollard_rho的模板要选好, 不然不是wa 就是 tle ,我太难了

#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <algorithm>
#include <iostream>
const int S=20;
using namespace std;typedef long long ll;
#define maxn 1000000ll factor[maxn];
int tot;ll muti_mod(ll a,ll b,ll c){    //返回(a*b) mod c,a,b,c<2^63a%=c;b%=c;ll ret=0;while (b){if (b&1){ret+=a;if (ret>=c) ret-=c;}a<<=1;if (a>=c) a-=c;b>>=1;}return ret;
}ll pow_mod(ll x,ll n,ll mod){  //返回x^n mod c ,非递归版if (n==1) return x%mod;int bit[64],k=0;while (n){bit[k++]=n&1;n>>=1;}ll ret=1;for (k=k-1;k>=0;k--){ret=muti_mod(ret,ret,mod);if (bit[k]==1) ret=muti_mod(ret,x,mod);}return ret;
}bool check(ll a,ll n,ll x,ll t){   //以a为基,n-1=x*2^t,检验n是不是合数ll ret=pow_mod(a,x,n),last=ret;for (int i=1;i<=t;i++){ret=muti_mod(ret,ret,n);if (ret==1 && last!=1 && last!=n-1) return 1;last=ret;}if (ret!=1) return 1;return 0;
}bool Miller_Rabin(ll n){ll x=n-1,t=0;while ((x&1)==0) x>>=1,t++;bool flag=1;if (t>=1 && (x&1)==1){for (int k=0;k<S;k++){ll a=rand()%(n-1)+1;if (check(a,n,x,t)) {flag=1;break;}flag=0;}}if (!flag || n==2) return 0;return 1;
}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,x0=rand()%x,y=x0,k=2;while (1){i++;x0=(muti_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){           //递归进行质因数分解Nif (!Miller_Rabin(n)){factor[tot++] = n;return;}ll p=n;while (p>=n) p=Pollard_rho(p,rand() % (n-1) +1);findfac(p);findfac(n/p);
}
int idx = 0 ;
struct node
{ll val , num ;node() {}node(ll val , ll num) : val(val) , num(num) {} bool operator<(const node &a) const {val < a.val ;}
}fac[maxn];
ll b[maxn] ;
bool solve(ll n)
{if (!Miller_Rabin(n)) {fac[++ idx] = {n , 1} ;}else{tot = 0;findfac(n);sort(factor , factor + tot) ;idx = 0 ;for(int i = 0 ; i < tot ;i ++){if(factor[i] != fac[idx].val) fac[++ idx] = {factor[i] , 1};else fac[idx].num ++ ;}}
}
ll get(ll n , ll p)
{ll res = 0 ;while(n){res += n / p ;n /= p ;}return res ;
}
int main(){srand(time(NULL));int t;scanf("%d",&t);while (t--){ll n , x , y ;scanf("%lld%lld%lld",&n , &x , &y);idx = 0 ;solve(x) ;for(int j = 1; j <= idx ;j ++) b[j] = 0 ;for(int i = 1; i <= n ;i ++){ll p ;scanf("%lld" , &p) ;for(int j = 1 ;j <= idx ;j ++)b[j] += get(p , fac[j].val)  ;}ll minx = 0 ;for(int j = 1; j <= idx ;j ++)b[j] = get(y , fac[j].val) - b[j] , minx = max(minx , b[j]);for(int j = 1; j <= idx ;j ++)if(b[j] > 0)minx = min(minx , b[j] / fac[j].num) ; printf("%lld\n" , minx) ;}
}

这篇关于E.Multiply Pollard_rho质因数分解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/646733

相关文章

Pollard‘s rho因子分解法——C语言实现

Pollard's rho的核心思想其实就是求p和q的倍数,而这样的倍数有无穷多个,当N值很小的时候,成功率还是很高的,当N值很大时,该算法就不灵了。 #include <stdio.h>#include <stdlib.h>int gcd(int x,int y){int z;while(y){z=x,x=y,y=z%y;}return x;}int f(int x,int c,i

Pollard‘s p-1因子分解法——C语言实现

前置知识 smooth与powersmooth 光滑数(smooth number),或译脆数,是一个可以因数分解为小质数乘积的正整数 如果一个整数的所有素因子都不大于B,我们称这个整数是B-Smooth数 如果一个整数的所有素因子的对应指数次幂不大于B,我们称这个整数是B-powersmooth数 720(24∗32∗51)720(24∗32∗51) 是一个5-smooth数,6-smoot

Plus and Multiply(1500)

Plus and Multiply 题面翻译 有一个无穷大的正整数集合 S S S,该集合按下面所述方法生成: 数字 1 1 1 在集合 S S S 中。 若数字 x x x 在该集合中,那么数 x × a x \times a x×a 和数 x + b x+b x+b 均在集合 S S S 中。(其中 a a a 与 b b b 为给定常数) 现在给出数 n ,

ABC 368 G - Add and Multiply Queries

原题链接:G - Add and Multiply Queries 题意:给出数组a和b,三种操作,第一种:以 1 i x 的形式给出。用x替换ai​。第二种:以 2 i x 的形式给出。用x代替 bi​ 。第三种:以3 l r的形式给出,初始值为0,从l到r每个位置上可以选择加上a[i],或者乘上b[i],输出最大值。 思路:链表+set+树状数组+二分。题目中给出了答案的范围不会超过1e1

Add and Multiply Queries

题目链接:G - Add and Multiply Queries 区间修改+区间查询可以用线段树来做,但是这边介绍树状数组的写法。首先将a数组和b数组分开考虑,对于a数组,因为是加法运算求区间和,因此我们可以采用树状数组+差分来写,对于数组b,我们已知如果b[i] =  1 ,那么不如就进行加法运算,所以我们把b数组中大于1的数加入到一个set集合中,记住set记录的是位置,不是数值,然后可以

[leetcode] 43. Multiply Strings(大数相乘)

Multiply Strings 描述 Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2. Note: 1. The length of both num1 and num2 is < 110. 2. Both num1 an

C# OpenCvSharp 代数运算-add、scaleAdd、addWeighted、subtract、absdiff、multiply、divide

在C#中使用OpenCvSharp进行图像处理时,理解和合理使用各种图像操作函数可以帮助我们实现许多实际应用中的需求。下面,我将详细介绍每个函数的使用,并给出与实际应用项目相关的示例,包括运算过程和运算结果。 1. add 函数 作用 将两幅图像进行相加,可以达到图像融合的目的。 示例 实际应用: 将两幅图像叠加,创建双重曝光效果。 using OpenCvSharp;class Prog

hdu3074(Multiply game)

纯模板,就是把单点更新,区间求和改为单点更新,区间求积。 题意:给出n个数,有m个操作,操作有:询问区间[L,R]中所有数的成绩、改变某一个数的值。 思路:线段树模版题。在每个结点设一个值保存乘积。   第二次做的时候错在了——int64位上; 由于成绩的结果较大要用--int64;所以有关输出的量都要用int64,其中包括find函数;结构中sum的定义,等;

POJ 1142 质因数分解

这题真是WA出翔了,用了上交的模板,然后坑死人不说……WA到最后才明天是a与b数组会出界啊……因为如果n很大的话,因数很多的话,就不行了。所以把那模板改成直接计算就过了,因为这题没有要输出它们的质因数与指数,所以可以这么做…… #include <iostream>#include <cstdio>#include <fstream>#include <algorithm>#incl

UVA - 11490 Just Another Problem (因数分解)

There is a wise saying “Nothingis unfair in love and war”. Probably that is why emperors of ancient days usedto use many funny and clever tricks to fool the opponents. The most commontechnique was