fork download
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define pb push_back
  4. typedef long long ll;
  5. #define SZ 233333
  6. const int MOD=1e9+7; //or any prime
  7. ll qp(ll a,ll b)
  8. {
  9. ll x=1; a%=MOD;
  10. while(b)
  11. {
  12. if(b&1) x=x*a%MOD;
  13. a=a*a%MOD; b>>=1;
  14. }
  15. return x;
  16. }
  17. namespace linear_seq {
  18. inline vector<int> BM(vector<int> x)
  19. {
  20. //ls: (shortest) relation sequence (after filling zeroes) so far
  21. //cur: current relation sequence
  22. vector<int> ls,cur;
  23. //lf: the position of ls (t')
  24. //ld: delta of ls (v')
  25. int lf,ld;
  26. for(int i=0;i<int(x.size());++i)
  27. {
  28. ll t=0;
  29. //evaluate at position i
  30. for(int j=0;j<int(cur.size());++j)
  31. t=(t+x[i-j-1]*(ll)cur[j])%MOD;
  32. if((t-x[i])%MOD==0) continue; //good so far
  33. //first non-zero position
  34. if(!cur.size())
  35. {
  36. cur.resize(i+1);
  37. lf=i; ld=(t-x[i])%MOD;
  38. continue;
  39. }
  40. //cur=cur-c/ld*(x[i]-t)
  41. ll k=-(x[i]-t)*qp(ld,MOD-2)%MOD/*1/ld*/;
  42. vector<int> c(i-lf-1); //add zeroes in front
  43. c.pb(k);
  44. for(int j=0;j<int(ls.size());++j)
  45. c.pb(-ls[j]*k%MOD);
  46. if(c.size()<cur.size()) c.resize(cur.size());
  47. for(int j=0;j<int(cur.size());++j)
  48. c[j]=(c[j]+cur[j])%MOD;
  49. //if cur is better than ls, change ls to cur
  50. if(i-lf+(int)ls.size()>=(int)cur.size())
  51. ls=cur,lf=i,ld=(t-x[i])%MOD;
  52. cur=c;
  53. }
  54. for(int i=0;i<int(cur.size());++i)
  55. cur[i]=(cur[i]%MOD+MOD)%MOD;
  56. return cur;
  57. }
  58. int m; //length of recurrence
  59. //a: first terms
  60. //h: relation
  61. ll a[SZ],h[SZ],t_[SZ],s[SZ],t[SZ];
  62. //calculate p*q mod f
  63. inline void mull(ll*p,ll*q)
  64. {
  65. for(int i=0;i<m+m;++i) t_[i]=0;
  66. for(int i=0;i<m;++i) if(p[i])
  67. for(int j=0;j<m;++j)
  68. t_[i+j]=(t_[i+j]+p[i]*q[j])%MOD;
  69. for(int i=m+m-1;i>=m;--i) if(t_[i])
  70. //miuns t_[i]x^{i-m}(x^m-\sum_{j=0}^{m-1} x^{m-j-1}h_j)
  71. for(int j=m-1;~j;--j)
  72. t_[i-j-1]=(t_[i-j-1]+t_[i]*h[j])%MOD;
  73. for(int i=0;i<m;++i) p[i]=t_[i];
  74. }
  75. inline ll calc(ll K)
  76. {
  77. for(int i=m;~i;--i)
  78. s[i]=t[i]=0;
  79. //init
  80. s[0]=1; if(m!=1) t[1]=1; else t[0]=h[0];
  81. //binary-exponentiation
  82. while(K)
  83. {
  84. if(K&1) mull(s,t);
  85. mull(t,t); K>>=1;
  86. }
  87. ll su=0;
  88. for(int i=0;i<m;++i) su=(su+s[i]*a[i])%MOD;
  89. return (su%MOD+MOD)%MOD;
  90. }
  91. inline int work(vector<int> x,ll n)
  92. {
  93. if(n<int(x.size())) return x[n];
  94. vector<int> v=BM(x); m=v.size(); if(!m) return 0;
  95. for(int i=0;i<m;++i) h[i]=v[i],a[i]=x[i];
  96. return calc(n);
  97. }
  98. }
  99. using linear_seq::work;
  100. int main()
  101. {
  102. cout<<work({1,1,2,3,5,8,13,21},10)<<"\n";
  103. }
  104.  
Success #stdin #stdout 0s 4376KB
stdin
Standard input is empty
stdout
89