Counting

Time:2021-10-14

preface

During the summer vacation, I saw an interview question from Tencent while watching C + + face to face.

The main idea of the problem is to find the value of (2 ^ 1e10)% 10000, which limits the time complexity.

There are no large numbers in Java and python in C + +. I wonder if readers can answer this question.

text

This problem can be solved by fast power.
Please listen to me in detail.

After learning about binary, we know that any number can be represented by a unique binary, that is to sayEach number can be uniquely expressed as the sum of the powers of 2 whose exponents are not repeated.

For example, suppose B has k bits in binary representation. Then B can be expressed as:

b=ck-12k-1+ck-22k-2+ck-32k-3+……+c121+c020

Common modes of fast exponentiation are:

  1. Given the values of a, B and P, find the value of (a ^ b)% p. a. B, P are all large numbers, 1 < = a, B, P < = 1e10
  2. Given the values of a, B and P, find the value of (a * b)% p. a. B, P are all large numbers, 1 < = a, B, P < = 1e10

1. (a^b)%p

From the above example:

b=ck-12k-1+ck-22k-2+ck-32k-3+……+c121+c020

Then a ^ B = ac~k-1~2k-1+ac~k-2~2k-2+ac~k-3~2k-3+……+ac~1~21+ac~0~20

Because the mathematical format support is not very good, post a figure to explain it.

4aPmWD.png

Algorithm analysis:

According to the above formula, we find that the original problem is transformed into the product of subproblems with the same form, and we can change from 2 in constant timek-1Item launch 2kItem.

The complexity of this algorithm is O (logn). We calculate logn 2KPower, and then take logn time to select the power corresponding to binary 1 to multiply.

Let’s practice:Calculate the value of (a ^ b)% p

4aFgsJ.png

#include

using namespace std;
typedef long long LL;
LL a,b,p;

int main()
{
    scanf("%lld%lld%lld",&a,&b,&p);
    LL ans=1%p;        //  Initial ans
    while(b)
    {
        if(b&1) ans=ans*a%p;
        a=a*a%p;       // Repeated square
        
        b>>=1;
    }
    printf("%lld\n",ans);
    return 0;
}

2.(a*b)%p

Similar to the first template, similarly:

4aifC8.png

Let’s practice with a question:Find (a * b)% p

4aFbsH.png

#include
using namespace std;

typedef long long LL;
LL a,b,p;
LL ans;

int main()
{
    scanf("%lld%lld%lld",&a,&b,&p);
    while(b)
    {
        if(b&1) ans=(ans+a)%p;   //  Accumulate each 2 ^ k
        a=a*2%p;   
        b>>=1;
    }
    printf("%lld\n",ans);
    return 0;
}

matters needing attention

Because the data of fast power is very large, when using C + + to do questions, it is very slow to input test cases with simple CIN, which will lead to timeout.

Here are two suggestions:

  1. Add this desynchronization statement before CIN
cin.tie(nullptr)->sync_with_stdio(false);
  1. Use scanf () to read.

last

There are many questions about fast power, such as fast power matrix, calculating Fibonacci number and so on.

This article only talks about the initial order of fast power. I will share higher-order fast power knowledge for you later.

Well, that’s it first. See you next time!