0

This sequence satisfies a(n+2) = 2 a(n+1) + 2 a(n).

and also a(n)=[(1+sqrt(3))^(n+2)-(1-sqrt(3))^(n+2)]/(4sqrt(3)).

I am using C++ for me n can vary from 1 to 10^ 9. I need the answers modulo (10^9)+7 But speed here is very important

My code with formula1 is slow for numbers > 10^7

#include <iostream>
#define big unsigned long long int
#include<stdlib.h>
int ans[100000001]={0};

big m  =1000000007;
using namespace std;
int main()
{
    //cout << "Hello world!" << endl;
    big t,n;
    cin>>t;
    big a,b,c;
    a=1;
    b=3;
    c=8;
    ans[0]=0;
    ans[1]=1;
    ans[2]=3;
    ans[3]=8;
    for(big i=3;i<=100000000;i++)
        {
            ans[i]=(((((ans[i-2])+(ans[i-1])))%m)<<1)%m;

        }

//    while(t--)
//    {
//        int f=0;
//        cin>>n;
//        if(n==1){
//        cout<<1<<endl;f++;}
//        if(n==2){
//        cout<<3<<endl;
//        f++;
//        }
//        if(!f){
//        a=1;
//        b=3;
//        c=8;
//        for(big i=3;i<=n;i++)
//        {
//            c=(((((a)+(b
//                         )))%m)<<1)%m;
//            a=b%m ;
//            b=c%m;
//        }
//        cout<<ans[n]<<endl;
//        }
//    }
while(t--)
{
    cin>>n;
    if(n<=100000000)
    cout<<ans[n]<<endl;
    else
    cout<<rand()%m;
}
    return 0;
}

I want a faster method. How can I compute the nth term using the second formula.Is there any trick to calculate modular powers of decimals very quickly? Do you have any suggestions for faster generation of this sequence?

Please help

  • 2
    Why is there a seemingly endless series of questions on SO involving mod 1e9+7? – Oliver Charlesworth Jul 02 '12 at 22:55
  • 2
    @OliCharlesworth It's a common modulus for online judges. I guess it's used so often because it's simple in decimal form, prime, and there's no problem calculating powers modulo that with 64-bit integers. – Daniel Fischer Jul 02 '12 at 22:57
  • 5
    The reason for this one is http://www.codechef.com/JULY12/problems/CSUMD. The OP should probably be honest about these things – nikhil Jul 03 '12 at 05:07
  • Well Nilhil no offence,but I did know that fibonacci sequence could be generated in logn times .I didnt know that method could bee generalized to solve any linear recursion.Also,I am not a shallow minded person to just ask for code,I am asking for approach,also I did derive the recursion.They are somethings you can not come to know even with google as you don't know what to search for.Good luck to you.Hope you don't mind.Thanks everyone. – Ajax Aristodemos Jul 03 '12 at 19:10

2 Answers2

10

You can calculate values of sequences with a linear recurrence relation in O(log n) steps using the matrix method. In this case, the recurrence matrix is

2 2
1 0

The n-th term of the sequence is then obtained by multiplying the n-th power of that matrix with the two initial values.

The recurrence immediately translates to

|x_n    |   |2 2|   |x_(n-1)|
|x_(n-1)| = |1 0| * |x_(n-2)|

thus

|x_(n+1)|   |2 2|^n   |x_1|
|x_n    | = |1 0|   * |x_0|.

In this case the initial conditions give, x_1 = 1, x_2 = 3 lead to x_0 = 0.5, a non-integer value, hence the calculation should rather be

|x_(n+1)|   |2 2|^(n-1)   |x_2|
|x_n    | = |1 0|       * |x_1|.

To get the value modulo some number, calculate the power of the matrix modulo that number.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • This is fascinating - in all the maths I have studied I have never seen this approach before. I don't suppose you would be good enough to provide a link to where this is explained or at least the name for this method so I can go and take a more in depth look??? – mathematician1975 Jul 02 '12 at 22:40
  • 1
    For the Fibonacci sequence, see [here](http://en.wikipedia.org/wiki/Fibonacci_number#Matrix_form), more general [here](http://en.wikipedia.org/wiki/Linear_recursive_sequence#Solving_via_linear_algebra). For recurrences including many previous values, it's better to reduce it to calculating `X^n` modulo the characteristic polynomial (thanks for Cayley-Hamilton ;), but for just the two previous values that's usually not a big difference. – Daniel Fischer Jul 02 '12 at 22:51
  • I don't think this produces the series that the OP wants. For n = 2 Upon squaring the matrix and multiplying it with `[1 3]` the initial terms I get `[8 1]`. Sorry if the formatting isn't too good. Could you explain how it works? – nikhil Jul 03 '12 at 05:30
  • 1
    @nikhil You have to multiply with `[3,1]`, `[[2 2],[1 0]] * [3,1] = [2*3+2*1,1*3+0*1] = [8,3]`, next, `[[2 2],[1 0]] * [8,3] = [22,8]` etc. Will edit to make that clear. – Daniel Fischer Jul 03 '12 at 09:59
  • @DanielFischer : You sir are a genius! Thanks again for another wonderful explanation. Might I also ask how you deduced this recursion? – nikhil Jul 03 '12 at 12:35
  • 1
    Ask you may, @nikhil, but I'm afraid I can't answer that, lost in the distant past. Besides, I wasn't the first to rediscover that recursion, afaik it's classical (meaning it's known since at least the 19-th century) and everybody investigating linear recursive sequences rediscovers it unless (s)he finds it in the literature before. – Daniel Fischer Jul 03 '12 at 12:43
  • Daniel Sir this method is also too slow although it just takes 29 steps for n=10^9 – Ajax Aristodemos Jul 04 '12 at 07:06
  • @AjaxAristodemos My implementation computes and prints the value for 100000 numbers in the region of 10^9 in under 60 milliseconds (each from scratch, output redirected to file, ~320ms when printing to console). What sort of time constraints have you? – Daniel Fischer Jul 04 '12 at 08:57
  • @AjaxAristodemos: Are you sure you are using an O(logN) exponentiation algorithm to exponentiate the matrix? – JPvdMerwe Jul 05 '12 at 13:37
  • @AjaxAristodemos: I implemented Daniel Fischer’s suggestion, and the time to calculate a(1000000000) is tiny, less than 900 CPU cycles on an Intel Xeon (so less than half a microsecond on a 2.27 GHz MacPro4,1). As a double-check, using a(0)=1, a(1)=3, I get a(500000000)=590171869. Anybody else? – Eric Postpischil Jul 06 '12 at 16:33
  • Confirmed, @EricPostpischil, around 900 cycles. 3.4 seconds for the 10 million values `a(5*10^8)` to `a(51*10^7-1)` (just calculating and summing, not printing each individually). – Daniel Fischer Jul 06 '12 at 17:42
  • @EricPostpischil:I tried out Daniel Fischer ' s algorithm but it is too slow.I need 1 million worst case answers in around 1 second. – Ajax Aristodemos Jul 10 '12 at 06:27
  • @DanielFischer:please help sir – Ajax Aristodemos Jul 10 '12 at 06:27
  • @AjaxAristodemos If you need to print one million numbers to the console in a second, that isn't going to happen using the standard output routines anytime soon. Printing them to a file is possible in a second, however, if you first build up the output string and only then call `(f)printf`, but only if the machine the code runs on is fast enough. For the computation, I can imagine one could push it down to ~500 cycles per number, but my wisdom ends at ~820 cycles. Anyhow, what machine does it run on, and what are the precise specs for the task? – Daniel Fischer Jul 10 '12 at 10:06
  • @AjaxAristodemos: I suspect the two parts you are missing are (a) Multiplying two matrices modulo 1,000,000,007 and (b) Raising a matrix to non-negative integer powers in an efficient way. – Eric Postpischil Jul 10 '12 at 17:52
0

I don't want to spoil of the fun of exploring the solution of algorithmic puzzles, so I'll just give you a starting hint: What you have there is basically a Fibonacci sequence with a few confusing elements.

hege
  • 987
  • 4
  • 15
  • 1
    There is a very specific question posted by OP. Numbers greater than 10E7 is a problem. This is not a good answer nor hint. – Captain Giraffe Jul 02 '12 at 22:44
  • 1
    The problem is that he wants to calculate it linearly, and he needs to think out of the box first, before he can go on with solving it: see DF's answer for example, which I tried evade, but shows the path more in depth. At any rate, the first step is always to know what information are you looking for. IMHO – hege Jul 02 '12 at 22:50
  • I was unaware of the online competition stuff. However this is a comment you can make. Not an answer. – Captain Giraffe Jul 02 '12 at 23:13
  • In my opinion it's a great hint. What's the point of spoon feeding the OP when they are trying to solve a problem in a coding contest. – nikhil Jul 03 '12 at 05:10