import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigInteger; /** * * @author felke */ public class fib { private static final BigInteger max = new BigInteger("10000000000000000000"); private static final long[] levelValue = new long[19]; private static final int[] levelCount = new int[19]; private static BigInteger multiply(BigInteger x, BigInteger y) { BigInteger result = x.multiply(y); return result.mod(max); } private static BigInteger fastFibonacciDoubling(long n) { BigInteger a = BigInteger.ZERO; BigInteger b = BigInteger.ONE; int m = 0; for (int i = 64 - Long.numberOfLeadingZeros(n); i >= 0; i--) { BigInteger d = multiply(a, b.shiftLeft(1).subtract(a)); BigInteger e = multiply(a, a).add(multiply(b, b)); a = d; b = e; m *= 2; if (((n >>> i) & 1) != 0) { BigInteger c = a.add(b); a = b; b = c; m++; } } return a; } private static void fillLevelValues() { levelValue[0]=1; levelCount[0]=61; levelValue[1]=60; levelCount[1]=6; levelValue[2]=300; levelCount[2]=6; levelValue[3]=1500; levelCount[3]=11; for(int k=4;k<19;k++) { levelValue[k] = levelValue[k-1]*10; levelCount[k] = 11; } } private static Long calculate(long result, String value, int level) { if(level == value.length()){ return result; } //System.out.println(result + " " + value + " " + level); for(int k=0; k<levelCount[level]; k++) { BigInteger fib = fastFibonacciDoubling(result); //System.out.println(level + ": " + result + " " + fib); //System.out.println("Examining: " + result + ": " + fib); Character extractedDigit = extractDigit(fib, level); if(extractedDigit != null && extractDigit(fib, level).equals(value.charAt(value.length()-level-1))) { Long solution = calculate(result, value, level+1); if(solution != null) { return solution; } } result+= levelValue[level]; } return null; } private static Character extractDigit(BigInteger number, int level) { String s = number.toString(); if (s.length()>level) { return s.charAt(s.length()-level-1); } return null; } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String value = br.readLine(); fillLevelValues(); Long result; result = calculate(0, value, 0); if(result == null){ System.out.println("NIE"); } else { System.out.println(result); } } }
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 113 114 115 116 117 118 119 120 121 122 123 124 125 | import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigInteger; /** * * @author felke */ public class fib { private static final BigInteger max = new BigInteger("10000000000000000000"); private static final long[] levelValue = new long[19]; private static final int[] levelCount = new int[19]; private static BigInteger multiply(BigInteger x, BigInteger y) { BigInteger result = x.multiply(y); return result.mod(max); } private static BigInteger fastFibonacciDoubling(long n) { BigInteger a = BigInteger.ZERO; BigInteger b = BigInteger.ONE; int m = 0; for (int i = 64 - Long.numberOfLeadingZeros(n); i >= 0; i--) { BigInteger d = multiply(a, b.shiftLeft(1).subtract(a)); BigInteger e = multiply(a, a).add(multiply(b, b)); a = d; b = e; m *= 2; if (((n >>> i) & 1) != 0) { BigInteger c = a.add(b); a = b; b = c; m++; } } return a; } private static void fillLevelValues() { levelValue[0]=1; levelCount[0]=61; levelValue[1]=60; levelCount[1]=6; levelValue[2]=300; levelCount[2]=6; levelValue[3]=1500; levelCount[3]=11; for(int k=4;k<19;k++) { levelValue[k] = levelValue[k-1]*10; levelCount[k] = 11; } } private static Long calculate(long result, String value, int level) { if(level == value.length()){ return result; } //System.out.println(result + " " + value + " " + level); for(int k=0; k<levelCount[level]; k++) { BigInteger fib = fastFibonacciDoubling(result); //System.out.println(level + ": " + result + " " + fib); //System.out.println("Examining: " + result + ": " + fib); Character extractedDigit = extractDigit(fib, level); if(extractedDigit != null && extractDigit(fib, level).equals(value.charAt(value.length()-level-1))) { Long solution = calculate(result, value, level+1); if(solution != null) { return solution; } } result+= levelValue[level]; } return null; } private static Character extractDigit(BigInteger number, int level) { String s = number.toString(); if (s.length()>level) { return s.charAt(s.length()-level-1); } return null; } public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String value = br.readLine(); fillLevelValues(); Long result; result = calculate(0, value, 0); if(result == null){ System.out.println("NIE"); } else { System.out.println(result); } } } |