Guest User

FIBEQN

a guest
Mar 31st, 2016
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.09 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define check(N, A, B) assert((ll)(N) >= (ll)(A) && (ll)(N) <= (ll)(B))
  3. using namespace std;
  4. typedef long long ll;
  5. const int mod = 1e9+7;
  6.  
  7. struct num{
  8.     ll a,b;
  9.   num(ll _a){
  10.     a = _a % mod; b = 0;
  11.   }
  12.     num(ll _a, ll _b){
  13.         a = _a % mod; b = _b % mod;
  14.         if(a < 0) a += mod;
  15.         if(b < 0) b += mod;
  16.     }
  17. };
  18. inline num add(num x, num y){
  19.     return num((x.a+y.a)%mod,(x.b+y.b)%mod);
  20. }
  21. inline num sub(num x, num y){
  22.     return num((x.a-y.a+mod)%mod,(x.b-y.b+mod)%mod);
  23. }
  24. num mult(num x, num y){
  25.     ll p = (x.a * y.a) % mod + (5ll * ((x.b * y.b) % mod))%mod;
  26.     p %= mod;
  27.     ll q = (x.a * y.b) % mod + (x.b * y.a) % mod;
  28.     q %= mod;
  29.     return num(p,q);
  30. }
  31. num exp(num x, ll n){
  32.     num ret = num(1);
  33.     while(n){
  34.         if(n&1ll) ret = mult(ret,x);
  35.         x = mult(x,x);
  36.         n >>= 1;
  37.     }
  38.     return ret;
  39. }
  40. ll inv(ll x){
  41.     return exp(num(x),mod-2).a;
  42. }
  43. num inverse(num x){
  44.     ll c = ((x.a * x.a)%mod) - ((5ll * ((x.b * x.b)%mod))%mod);
  45.     c %= mod;
  46.     c = (c+mod)%mod;
  47.     c = inv(c);
  48.     c = (c * x.a)%mod;
  49.     ll d = (- (x.a * x.a)%mod) + ((5ll * ((x.b * x.b)%mod))%mod);
  50.     d %= mod;
  51.     d = (d+mod)%mod;
  52.     d = inv(d);
  53.     d = (d * x.b)%mod;
  54.     return num(c,d);
  55. }
  56.  
  57. num gpsum(num a, ll n){
  58.   //(a**(n+1) - 1)/(a-1)
  59.   num ret = sub(exp(a,n+1),num(1));
  60.   ret = mult(ret,inverse(sub(a,num(1))));
  61.     // cout << "G: " << a.a << " " << a.b << " " << n << ": " << ret.a << " " << ret.b << endl;
  62.   return ret;
  63. }
  64. ll go(ll n, ll _k){
  65.   //Declaring Phi and Psi
  66.   num two_inv = inverse(num(2,0));
  67.     num phi = num(1,1);
  68.     phi = mult(phi, two_inv);
  69.     num psi = num(1,mod-1);
  70.     psi = mult(psi, two_inv);
  71.     // cout << "phi: " << phi.a << " " << phi.b << " : " << "psi: " << psi.a << " " << psi.b << endl;
  72.  
  73.   num k = num(_k);
  74.   num ret = sub(gpsum(mult(phi,k),n), gpsum(mult(psi,k),n));
  75.   ret = mult(ret, inverse(sub(phi,psi)));
  76.     assert(ret.b == 0);
  77.   return ret.a;
  78. }
  79.  
  80. int main(){
  81.   ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  82.   int Q; cin >> Q;
  83.   check(Q, 1, 1e9);
  84.   while(Q--){
  85.     ll N, K;
  86.     cin >> N >> K;
  87.     check(N, 1, 1e18);
  88.     check(K, 1, 1e18);
  89.     K %= mod;
  90.     cout << go(N, K) << endl;
  91.   }
  92. }
Add Comment
Please, Sign In to add comment