判断是否为素数 + 分解质因数(利用了Miller_Rabin和素数筛选法)
来源:互联网 发布:java培训哪个机构最好 编辑:程序博客网 时间:2024/05/16 06:06
http://acm.hdu.edu.cn/showproblem.php?pid=5778
题意:T组数据,给x求y。y满足个条件1.与x差的绝对值最小 2.质因数分解每个元素恰好出现两次。x <= 10 ^18
解析:直接枚举sqrt(y),先判断开方后的这个数是否为素数(利用logn的算法),如果不是判断。开方后的这个数中分解质因数的因数每个元素最多出现一次,暴力枚举即可
另:要注意题目中的条件y >= 2
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <sstream>#include <string>#include <algorithm>#include <list>#include <map>#include <vector>#include <queue>#include <stack>#include <cmath>#include <cstdlib>using namespace std;#define maxn (100000 + 50)typedef long long LL;LL fabs2(long long x){ if(x < 0) return -x; return x;}//接口:if(Miller_Rabin(n) == true)//为真则为素数bool isPrime[maxn];LL primeList[maxn],primeCount = 0;void primeInit(LL n){ memset(isPrime,true,sizeof(isPrime));//初始化认为全部是素数 int m = sqrt(n + 0.5); for(int i = 2; i <= m; i ++) { if(isPrime[i])//判断是素数 { for(int j = i * i; j <= n; j += i){ isPrime[j] = false; } } } for(int i = 2; i <= n; i ++) { if(isPrime[i]){ primeList[primeCount] = i; primeCount ++; } }}const int S=20;//随机算法判定次数,S越大,判错概率越小long long mult_mod(long long a,long long b,long long c){ a%=c; b%=c; long long ret=0; while(b) { if(b&1) { ret+=a; ret%=c; } a<<=1; if(a>=c)a%=c; b>>=1; } return ret;}//计算 x^n %clong long pow_mod(long long x,long long n,long long mod)//x^n%c{ if(n==1)return x%mod; x%=mod; long long tmp=x; long long ret=1; while(n) { if(n&1) ret=mult_mod(ret,tmp,mod); tmp=mult_mod(tmp,tmp,mod); n>>=1; } return ret;}//以a为基,n-1=x*2^t a^(n-1)=1(mod n) 验证n是不是合数//一定是合数返回true,不一定返回falsebool check(long long a,long long n,long long x,long long t){ long long ret=pow_mod(a,x,n); long long last=ret; for(int i=1; i<=t; i++) { ret=mult_mod(ret,ret,n); if(ret==1&&last!=1&&last!=n-1) return true;//合数 last=ret; } if(ret!=1) return true; return false;}// Miller_Rabin()算法素数判定//是素数返回true.(可能是伪素数,但概率极小)//合数返回false;bool Miller_Rabin(long long n){ if(n<2)return false; if(n==2)return true; if((n&1)==0) return false;//偶数 long long x=n-1; long long t=0; while((x&1)==0) { x>>=1; t++; } for(int i=0; i<S; i++) { long long a=rand()%(n-1)+1;//rand()需要stdlib.h头文件 if(check(a,n,x,t)) return false;//合数 } return true;}int main(){//freopen("in.txt","r",stdin); primeInit(100000); int T; scanf("%d",&T); while(T--) { int tcnt = 0; bool flag; LL ans; LL x; long long left,right; scanf("%I64d",&x); left = sqrt(x) ; right = sqrt(x) + 1 ; int cnt = 0; LL l,r; while(1) { l =left + cnt; if(l < 2) { cnt++; continue; } if(Miller_Rabin(l) == true)//为真则为素数 { ans = fabs2(l *l - x); break; } flag = true; for(int i = 0; i*i <= l && i < primeCount; i ++) { tcnt = 0; while(l% primeList[i] == 0) { l = l / primeList[i]; tcnt ++; } if(tcnt > 1) { flag = false; break; } } if(flag == true) { ans = fabs2(x - (left + cnt) * (left + cnt)); break; } cnt ++; } cnt = 0; while(1){ r = right - cnt; if(r < 2) break; if(Miller_Rabin(r) == true)//为真则为素数 { ans =min(ans, fabs2(r*r -x)); break; } flag = true; for(int i = 0; i*i <= r&& i < primeCount; i ++) { tcnt = 0; while(r% primeList[i] == 0) { r = r / primeList[i]; tcnt ++; } if(tcnt > 1) { flag = false; break; } } if(flag == true) { ans = min(ans,fabs2(x - (right - cnt) * (right - cnt))); break; } cnt ++; } printf("%I64d\n",ans); } return 0;}
0 0
- 判断是否为素数 + 分解质因数(利用了Miller_Rabin和素数筛选法)
- miller_rabin素数判断和pollard_rho的素数因子分解算法
- Miller_Rabin素数测试与Pollard_Rho分解质因数
- 判断素数及质因数分解
- sdnu第一场选拔赛--Miller_Rabin算法判断是否为素数
- 判断素数(Miller_Rabin算法)
- POJ 1181 大整数是否为素数以及求大整数的质因数-数论-(Miller_rabin+Pollard_rho)
- 质因数分解 和 判断是否为质数
- Miller_Rabin 算法进行素数测试和分解
- miller_rabin hdu 2138 判断是否是素数
- 素数筛选 素数分解
- Miller_Rabin 判断素数
- Miller_Rabin 大素数判断
- 判断是否为素数
- 判断是否为素数
- 判断是否为素数
- 判断是否为素数
- 判断是否为素数
- 51nod 1133 不重叠的线段(贪心)
- 信号与槽机制
- sublime text安装及package control的安装
- 借助 Lucene.Net 构建站内搜索引擎(上)
- Spring Mvc 的原理
- 判断是否为素数 + 分解质因数(利用了Miller_Rabin和素数筛选法)
- 用Android studio软件导入eclipse中编程的老软件
- POJ-Colored Sticks(字典树+并查集+欧拉回路)
- FMDB FMDB的使用方法
- HDOJ 5778 abs
- 温故而知新(一)TreeMap
- 使用impdp导入lob字段数据hang问题处理
- Javascript - 闭包
- Python——10模块