这是我的代码:
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
import java.security.SecureRandom;
public class Solution {
static BigDecimal result;
static Double y = 0.0;
static int o;
static int[] factors = new int[1];
static int current = 0;
public static void main(String[] args) {
Scanner a1 = new Scanner(System.in);
int b = a1.nextInt();
o = b;
result = new BigDecimal(Integer.valueOf(b));
BigInteger N = new BigInteger(Integer.toString(b - 1));
factor(N);
boolean isPrimitive = true;
for (int i1 = 2; i1 < 10000;i1++) {
isPrimitive = true;
//System.out.println("Enter the value of a large prime no");
BigInteger value = new BigInteger(String.valueOf(o-1));
//System.out.println("\nEnter the value of alpha");
BigInteger checking = new BigInteger(String.valueOf(i1));
BigInteger bigValue = new BigInteger(String.valueOf(o));
for(int i=0;i<factors.length;i++)
{
BigInteger temp = checking.pow(factors[i]);
// System.out.println("checking "+i1+": "+temp+" mod "+o+" = " + (temp.mod(new BigInteger(String.valueOf(o)))));
if ((temp.mod(bigValue)).equals(BigInteger.ONE)) {
isPrimitive = false;
break;
}
}
if(isPrimitive) {
System.out.print(i1+" ");
break;
}
else{
//System.out.println("not primitive roots");
}
}
System.out.println(result.toBigInteger());
}
private final static BigInteger ZERO = new BigInteger("0");
private final static BigInteger ONE = new BigInteger("1");
private final static BigInteger TWO = new BigInteger("2");
private final static SecureRandom random = new SecureRandom();
public static BigInteger rho(BigInteger N) {
BigInteger divisor;
BigInteger c = new BigInteger(N.bitLength(), random);
BigInteger x = new BigInteger(N.bitLength(), random);
BigInteger xx = x;
// check divisibility by 2
if (N.mod(TWO).compareTo(ZERO) == 0) return TWO;
do {
x = x.multiply(x).mod(N).add(c).mod(N);
xx = xx.multiply(xx).mod(N).add(c).mod(N);
xx = xx.multiply(xx).mod(N).add(c).mod(N);
divisor = x.subtract(xx).gcd(N);
} while ((divisor.compareTo(ONE)) == 0);
return divisor;
}
public static void factor(BigInteger N) {
//System.out.println("result = "+result);
if (N.compareTo(ONE) == 0) return;
if (N.isProbablePrime(20)) {
// System.out.println("n = "+N);
if ((N.doubleValue() != (y)) &&N.doubleValue() != (1.0) ) {
// System.out.println("j = "+String.valueOf(1.0 - (1.0/(N.doubleValue()))));
BigDecimal j = new BigDecimal(String.valueOf(1.0 - (1.0/(N.doubleValue()))));
//System.out.println("result = " +result+" * "+j);
result = new BigDecimal(String.valueOf(result.doubleValue() * j.doubleValue()));
//System.out.println(result.multiply(j));
//System.out.println((String.valueOf(1.0 - (1.0/(N.doubleValue())))));
y = N.doubleValue();
if (current == factors.length) {
int[] temp = new int[factors.length+1];
for (int i = 0; i < factors.length;i++) {
temp[i] = factors[i];
}
factors = temp;
}
factors[current] = o/y.intValue();
// System.out.println(o+"/"+y.intValue());
current++;
//System.out.println("result = "+result);
}
return;
}
BigInteger divisor = rho(N);
factor(divisor);
factor(N.divide(divisor));
}
}
我试图找到素数的第一个原始根,然后是原始根的数量。找到金额对于任何数字来说都没有问题,但找到第一个数字应该适用于某个系统上任何数量高达10亿的数字,其他人已经成功。它适用于高达一百万左右的所有值,但它不适用于999994267.我不知道如何进一步优化它。我花了大概18个小时。老实说,我无法解决这个问题。有什么建议吗?
数学说明: 它需要给定数字o的因子,并测试每个数字2,如果它因此/因子[1,2,...] = 1,如果没有任何因素,它会打破并打印数字。
PS。有可能,正如许多其他人在同一系统上所做的那样。
答案 0 :(得分:0)
好的,感谢上面的@IgorNikolaev在我的问题的评论中,我已经找到了问题并解决了它。要完全优化modPow操作,您需要使用模运算。
以下是他提供的一些非常有帮助的链接:
en.wikipedia.org/wiki/Modular_arithmetic
en.wikipedia.org/wiki/Modular_exponentiation
以下是我根据这些链接编写的代码:
private static BigInteger fastModPow(BigInteger base, BigInteger exponent, final BigInteger modulo) {
BigInteger result = BigInteger.ONE;
while (exponent.compareTo(BigInteger.ZERO) > 0) {
if (exponent.testBit(0))
result = (result.multiply(base)).mod(modulo);
exponent = exponent.shiftRight(1);
base = (base.multiply(base)).mod(modulo);
}
return result.mod(modulo);
}
正如您将在第一个链接中看到的那样,它会绕过&#34;包装&#34;找到权力的模式。
感谢大家的帮助。