Jzzhu and Sequences

Jzzhu and Sequences
Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u

Description

Jzzhu has invented a kind of sequences, they meet the following property:

You are given x and y, please calculate fn modulo 1000000007(109 + 7).

Input

The first line contains two integers x and y(|x|, |y| ≤ 109). The second line contains a single integer n(1 ≤ n ≤ 2·109).

Output

Output a single integer representing fn modulo 1000000007(109 + 7).

Sample Input

Input
2 3
3
Output
1
Input
0 -1
2
Output
1000000006

Hint

In the first sample, f2 = f1 + f33 = 2 + f3f3 = 1.

In the second sample, f2 =  - 1 - 1 modulo (109 + 7) equals (109 + 6).


  構造矩陣

                                            f3 = f2 - f1;       ====>    

                            f4 =  f3 - f2;       ====>         f4 = - f1;

                                                   

                                       ( -1  1 )   (  f1 )      ----->  (  f3 )

                                      ( -1  0 )   (  f2 )      ----->   (  f4 )

                         ( -1  1 ) ( -1  1 )   (  f1 )      ----->  (  f5 )

                          ( -1  0 )( -1  0 )   (  f2 )      ----->   (  f6 )


以此類推, 分類討論

          當n是奇數時,乘以矩陣的(n/2 - 1)次方

     當n是偶數時,乘以矩陣的(n/2 )次方

   當時做題的時候推出了這種思想,細想想還有其他更爲簡便的方法

#include <iostream>
#include <cstdio>
#include <cstring> 
#define Mod 1000000007
int n;
struct Node
{
	int m[3][3];
	int x;
	int y;
}pt , st , dt;
Node Pow(Node a, Node b)
{
	  memset(dt.m , 0 , sizeof(dt.m));
	   	 dt.x = a.x;
	   	  dt.y = b.y;
	for(int i = 1 ; i <= a.x; i++)
	   {
	   	 for(int k = 1; k <= a.y; k++)
	   	  {
	   	     if(a.m[i][k] == 0)
				 continue;
				 {
				   for(int j = 1; j <= b.y; j++)
				    {
				    	dt.m[i][j] = ((dt.m[i][j] + a.m[i][k] * b.m[k][j]) % Mod) % Mod;

					}
				}  	 
		}
	  }
	  return dt;
}
void  quickpow(int n)
{   
	  while(n)
	{
	   if(n % 2 == 1)	
		 pt = Pow(st , pt);
		n = n / 2;
		 st = Pow(st , st);
	}
 } 
int main()
{ 
        long long int f1,f2,n;
        scanf("%lld %lld",&f1,&f2);
        scanf("%lld",&n);
        memset(pt.m , 0 ,sizeof(pt.m)); 
        memset(st.m , 0 , sizeof(st.m));
   	    pt.m[1][1] = pt.m[2][2] = 1;  //初始化單位矩陣 
   	    st.m[1][2] = 1;
   	    st.m[1][1] = st.m[2][1] = -1;//已知矩陣 
   	    pt.x = pt.y = 2;
   	    st.x = st.y = 2; //矩陣的行列長度
		   long long int t; 
		  long long  int sum;
   	        if( n % 2 == 1)
		   {
		   	  t = n / 2;
		      quickpow(t);
		      sum = pt.m[1][1] * f1 + pt.m[1][2] * f2;
		       sum = sum%Mod;
		       if(sum < 0)
		        sum += Mod;
   	           printf("%lld\n",sum);
   	    }
   	      else
   	      {
   	      	    t = n /2 - 1;
   	      	    quickpow(t);
		      sum = pt.m[2][1] * f1 + pt.m[2][2] * f2;
		      sum = sum%Mod;
		      if(sum < 0)
		        sum += Mod;
   	           printf("%lld\n",sum);
			 }
	return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章