📌  相关文章
📜  查找给定系列的最后一位

📅  最后修改于: 2021-04-29 14:11:23             🧑  作者: Mango

给定整数n,找到该序列的最后一位, \displaystyle S =\sum_{i=0,\ 2^i\le n}^\infty \sum_{j=0}^n 2^{2^i + 2j}
从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的较大值而超时。

一种有效的方法是以易于计算的一般形式扩展上述表达式。

\displaystyle S =\sum_{i=0,\ 2^i\le n}^\infty \sum_{j=0}^n 2^{2^i + 2j}

\implies \displaystyle \sum_{i=0,\ 2^i\le n}^\infty \sum_{j=0}^n 2^{2^i}\cdot 2^{2j}

\implies\displaystyle\sum_{i=0,\ 2^i\le n}^\infty 2^{2^i} \cdot \sum_{j=0}^n 2^{2j}

\implies\displaystyle\sum_{i=0,\ 2^i\le n}^\infty 2^{2^i} \cdot \sum_{j=0}^n 4^j

  1. 第一表达\sum_{i=0,\ 2^i\le n}^\infty 2^{2^i}可以通过迭代直接计算一个循环的“I”直到2 I≤n的所有值。
  2. 第二表达\sum_{j=0}^n 4^j可以很容易地通过使用几何级数公式来计算,即
     \sum_{j=0}^n r^k = \dfrac{r^{n+1} - 1}{r-1}
  3. 最终答案将是两个步骤中这两个计算结果的乘积。但是在执行了这些表达式的任何计算部分之后,我们必须对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竞赛中要求