给定整数n,找到该序列的最后一位,
从I F(n)的总和,即= 0至2 I≤n,其中F(n)是2 2 I + 2J式中,j从0变化到n的总和。 n可以在0到10 17之间变化
例子:
Input: 2
Output: 6
Explanation:
After computing the above expression, the value
obtained is 216. Hence the last digit is 6.
Input: 3
Output: 0
幼稚的方法是运行两个循环,一个循环用于“ i”,另一个循环用于“ j”,并在对每个计算出的值取(模10)后计算该值。但是,这种方法肯定会因n的较大值而超时。
一种有效的方法是以易于计算的一般形式扩展上述表达式。
- 第一表达可以通过迭代直接计算一个循环的“I”直到2 I≤n的所有值。
- 第二表达可以很容易地通过使用几何级数公式来计算,即
- 最终答案将是两个步骤中这两个计算结果的乘积。但是在执行了这些表达式的任何计算部分之后,我们必须对10取模,以免发生溢出。
请参阅以下程序以了解更多信息。
C++
// C++ program to calculate to find last // digit of above expression #include
using namespace std; /* Iterative Function to calculate (x^y)%p in O(log y) */ long long powermod(long long x, long long y, long long p) { long long res = 1; // Initialise result x = x % p; // Update x if it is more than or // equal to p while (y > 0) { // If y is odd, multiply x with result if (y & 1LL) res = (res * x) % p; // y must be even now y = y >> 1LL; // y = y/2 x = (x * x) % p; } return res; } // Returns modulo inverse of a with respect to m // using extended Euclid Algorithm long long modInverse(long long a, long long m) { long long m0 = m, t, q; long long x0 = 0, x1 = 1; if (m == 1) return 0; while (a > 1) { // q is quotient q = a / m; t = m; // m is remainder now, process same as // Euclid's algo m = a % m, a = t; t = x0; x0 = x1 - q * x0; x1 = t; } // Make x1 positive if (x1 < 0) x1 += m0; return x1; } // Function to calculate the above expression long long evaluteExpression(long long& n) { // Initialize the result long long firstsum = 0, mod = 10; // Compute first part of expression for (long long i = 2, j = 0; (1LL << j) <= n; i *= i, ++j) firstsum = (firstsum + i) % mod; // Compute second part of expression // i.e., ((4^(n+1) - 1) / 3) mod 10 // Since division of 3 in modulo can't // be performed directly therefore we // need to find it's modulo Inverse long long secondsum = (powermod(4LL, n + 1, mod) - 1) * modInverse(3LL, mod); return (firstsum * secondsum) % mod; } // Driver code int main() { long long n = 3; cout << evaluteExpression(n) << endl; n = 10; cout << evaluteExpression(n); return 0; }
Java
// Java program to calculate to find last // digit of above expression class GFG{ /* Iterative Function to calculate (x^y)%p in O(log y) */ static long powermod(long x, long y, long p) { long res = 1; // Initialise result x = x % p; // Update x if it is more than or // equal to p while (y > 0) { // If y is odd, multiply x with result if ((y & 1L)>0) res = (res * x) % p; // y must be even now y = y >> 1L; // y = y/2 x = (x * x) % p; } return res; } // Returns modulo inverse of a with respect to m // using extended Euclid Algorithm static long modInverse(long a, long m) { long m0 = m, t, q; long x0 = 0, x1 = 1; if (m == 1) return 0; while (a > 1) { // q is quotient q = a / m; t = m; // m is remainder now, process same as // Euclid's algo m = a % m; a = t; t = x0; x0 = x1 - q * x0; x1 = t; } // Make x1 positive if (x1 < 0) x1 += m0; return x1; } // Function to calculate the above expression static long evaluteExpression(long n) { // Initialize the result long firstsum = 0, mod = 10; // Compute first part of expression for (long i = 2, j = 0; (1L << j) <= n; i *= i, ++j) firstsum = (firstsum + i) % mod; // Compute second part of expression // i.e., ((4^(n+1) - 1) / 3) mod 10 // Since division of 3 in modulo can't // be performed directly therefore we // need to find it's modulo Inverse long secondsum = (powermod(4L, n + 1, mod) - 1) * modInverse(3L, mod); return (firstsum * secondsum) % mod; } // Driver code public static void main(String[] args) { long n = 3; System.out.println(evaluteExpression(n)); n = 10; System.out.println(evaluteExpression(n)); } } // This code is contributed by mits
Python3
# Python3 program to calculate to find last # digit of above expression # Iterative Function to calculate (x^y)%p in O(log y) def powermod(x, y, p): res = 1; # Initialise result x = x % p; # Update x if it is more than or # equal to p while (y > 0): # If y is odd, multiply x with result if ((y & 1)>0): res = (res * x) % p; # y must be even now y = y >> 1; # y = y/2 x = (x * x) % p; return res; # Returns modulo inverse of a with respect to m # using extended Euclid Algorithm def modInverse(a, m): m0 = m; x0 = 0; x1 = 1; if (m == 1): return 0; while (a > 1): # q is quotient q = int(a / m); t = m; # m is remainder now, process same as # Euclid's algo m = a % m; a = t; t = x0; x0 = x1 - q * x0; x1 = t; # Make x1 positive if (x1 < 0): x1 += m0; return x1; # Function to calculate the above expression def evaluteExpression(n): # Initialize the result firstsum = 0; mod = 10; # Compute first part of expression i=2; j=0; while ((1 << j) <= n): firstsum = (firstsum + i) % mod; i *= i; j+=1; # Compute second part of expression # i.e., ((4^(n+1) - 1) / 3) mod 10 # Since division of 3 in modulo can't # be performed directly therefore we # need to find it's modulo Inverse secondsum = (powermod(4, n + 1, mod) - 1) * modInverse(3, mod); return (firstsum * secondsum) % mod; # Driver code n = 3; print(evaluteExpression(n)); n = 10; print(evaluteExpression(n)); # This code is contributed by mits
C#
// C# program to calculate to find last // digit of above expression class GFG{ /* Iterative Function to calculate (x^y)%p in O(log y) */ static long powermod(long x, long y, long p) { long res = 1; // Initialise result x = x % p; // Update x if it is more than or // equal to p while (y > 0) { // If y is odd, multiply x with result if ((y & 1)>0) res = (res * x) % p; // y must be even now y = y >> 1; // y = y/2 x = (x * x) % p; } return res; } // Returns modulo inverse of a with respect to m // using extended Euclid Algorithm static long modInverse(long a, long m) { long m0 = m, t, q; long x0 = 0, x1 = 1; if (m == 1) return 0; while (a > 1) { // q is quotient q = a / m; t = m; // m is remainder now, process same as // Euclid's algo m = a % m; a = t; t = x0; x0 = x1 - q * x0; x1 = t; } // Make x1 positive if (x1 < 0) x1 += m0; return x1; } // Function to calculate the above expression static long evaluteExpression(long n) { // Initialize the result long firstsum = 0, mod = 10; // Compute first part of expression for (int i = 2, j = 0; (1 << j) <= n; i *= i, ++j) firstsum = (firstsum + i) % mod; // Compute second part of expression // i.e., ((4^(n+1) - 1) / 3) mod 10 // Since division of 3 in modulo can't // be performed directly therefore we // need to find it's modulo Inverse long secondsum = (powermod(4L, n + 1, mod) - 1) * modInverse(3L, mod); return (firstsum * secondsum) % mod; } // Driver code public static void Main() { long n = 3; System.Console.WriteLine(evaluteExpression(n)); n = 10; System.Console.WriteLine(evaluteExpression(n)); } } // This code is contributed by mits
PHP
0) { // If y is odd, multiply // x with result if (($y & 1) > 0) $res = ($res * $x) % $p; // y must be even now $y = $y >> 1; // y = y/2 $x = ($x * $x) % $p; } return $res; } // Returns modulo inverse of a // with respect to m using // extended Euclid Algorithm function modInverse($a, $m) { $m0 = $m; $x0 = 0; $x1 = 1; if ($m == 1) return 0; while ($a > 1) { // q is quotient $q = (int)($a / $m); $t = $m; // m is remainder now, process // same as Euclid's algo $m = $a % $m; $a = $t; $t = $x0; $x0 = $x1 - $q * $x0; $x1 = $t; } // Make x1 positive if ($x1 < 0) $x1 += $m0; return $x1; } // Function to calculate the // above expression function evaluteExpression($n) { // Initialize the result $firstsum = 0; $mod = 10; // Compute first part of expression for ($i = 2, $j = 0; (1 << $j) <= $n; $i *= $i, ++$j) $firstsum = ($firstsum + $i) % $mod; // Compute second part of expression // i.e., ((4^(n+1) - 1) / 3) mod 10 // Since division of 3 in modulo can't // be performed directly therefore we // need to find it's modulo Inverse $secondsum = (powermod(4, $n + 1, $mod) - 1) * modInverse(3, $mod); return ($firstsum * $secondsum) % $mod; } // Driver code $n = 3; echo evaluteExpression($n) . "\n"; $n = 10; echo evaluteExpression($n); // This code is contributed by mits ?>
输出:
0 8
时间复杂度: O(log(n))
辅助空间: O(1)注意:在TCS Code vita竞赛中要求。