This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
using namespace std;
using namespace __gnu_pbds;
 
#define fi first
#define se second
#define mp make_pair
#define pb push_back
 
typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long double ld; 
typedef tree<ii, null_type, less<ii>, rb_tree_tag, tree_order_statistics_node_update> pbds;
const int MOD=1e9+7;
int add(int a, int b)
{
	a+=b;
	while(a>=MOD) a-=MOD;
	return a;
}
int mult(int a, int b)
{
	return (a*1LL*b)%MOD;
}
vector<int> getZeckendorf(vi a)
{
	sort(a.rbegin(),a.rend());
	while(1)
	{
		vi nw; bool reset=0;
		/*
		for(int x:a)
		{
			cerr<<x<<' ';
		}
		cerr<<'\n';
		*/
		for(int i=0;i<a.size();i++)
		{
			if(reset)
			{
				nw.pb(a[i]); continue;
			}
			if(i+1==int(a.size()))
			{
				nw.pb(a[i]); break;
			}
			if(a[i]==a[i+1])
			{
				if(a[i]==1)
				{
					nw.pb(2); i++; reset=1; continue;
				}
				else if(a[i]==2)
				{
					nw.pb(1); nw.pb(1); reset=1; continue;
				}
				else
				{
					nw.pb(a[i]+1); nw.pb(a[i]-2); i++; reset=1; continue;
				}
			}
			else if(a[i]-a[i+1]==1)
			{
				nw.pb(a[i]+1); i++; reset=1;
			}
			else
			{
				nw.pb(a[i]); 
			}
		}
		sort(nw.rbegin(),nw.rend());
		a=nw;
		if(!reset) break;
	}
	return a;
}
int solve(vi vec) //solve given zeckendorf monkaS
{
	reverse(vec.begin(),vec.end());
	vector<int> dp[2];
	dp[0].assign(int(vec.size()),0);
	dp[1].assign(int(vec.size()),0);
	dp[0][0] = (vec[0]-1)/2;
	dp[1][0] = add(dp[0][0], 1);
	int n=vec.size();
	for(int i=1;i<n;i++)
	{
		int x=vec[i-1]; int y=vec[i];
		if((y-x)&1)
		{
			dp[1][i] = mult(dp[1][i-1], (y-x+1)/2);
			dp[0][i] = mult(dp[1][i-1], (y-x-1)/2);
		}
		else
		{
			dp[0][i] = add(mult((y-x)/2 - 1, dp[1][i-1]), dp[0][i-1]);
			dp[1][i] = add(mult((y-x)/2, dp[1][i-1]), dp[0][i-1]);
		}
	}
	return dp[1][n-1];
}
struct matrix
{
	int a[2][2];
	matrix()
	{
		memset(a,0,sizeof(a));
	}
};
matrix unit;
matrix operator*(matrix a, matrix b)
{
	matrix c;
	for(int i=0;i<2;i++)
	{
		for(int j=0;j<2;j++)
		{
			c.a[i][j]=0;
			for(int k=0;k<2;k++)
			{
				c.a[i][j]=add(c.a[i][j],mult(a.a[i][k], b.a[k][j]));
			}
		}
	}
	return c;
}
matrix init(int d)
{
	matrix c;
	c.a[0][0] = 1; c.a[0][1] = d-1;
	c.a[1][0] = 1; c.a[1][1] = d;
	return c;
}
matrix st[422222];
void build(int id, int l, int r)
{
	if(r-l<2)
	{
		st[id]=unit; return ;
	}
	int mid=(l+r)>>1;
	build(id*2,l,mid); build(id*2+1,mid,r);
	st[id]=st[id*2+1]*st[id*2];
}
void update(int id, int l, int r, int pos, matrix v)
{
	if(pos<l||pos>=r) return ;
	if(r-l<2)
	{
		st[id]=v; return ;
	}	
	int mid=(l+r)>>1;
	update(id*2,l,mid,pos,v); update(id*2+1,mid,r,pos,v);
	st[id]=st[id*2+1]*st[id*2];
}
int a[111111];
int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	srand(time(NULL));
	int n; cin>>n;
	//n=15; cout<<n<<endl;
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
		//a[i]=rand()%15+1;
		//cout<<a[i]<<' ';
	}
	//cout<<endl;
	unit=matrix();
	unit.a[0][0]=unit.a[1][1]=1; 
	if(n<=100)
	{
		vi vec;
		for(int i=0;i<n;i++)
		{
			vec.pb(a[i]);
			vi nw = getZeckendorf(vec);
			cout<<solve(nw)<<'\n';
		}
	}
	else
	{
		vi coord;
		for(int i=0;i<n;i++)
		{
			coord.pb(a[i]);
		}
		sort(coord.begin(),coord.end());
		set<int> S;
		build(1,0,n);
		for(int i=0;i<n;i++)
		{
			S.insert(a[i]); int pos = lower_bound(coord.begin(),coord.end(),a[i])-coord.begin();
			auto it = S.lower_bound(a[i]);
			if(it==S.begin())
			{
				it++;
				if(it==S.end())
				{
					update(1,0,n,pos,init(a[i]/2));
				}
				else
				{
					int idnext = lower_bound(coord.begin(),coord.end(),(*it))-coord.begin();
					update(1,0,n,pos,init(a[i]/2));
					update(1,0,n,idnext,init(((*it)-a[i])/2));
				}
			}
			else
			{
				if(next(it)==S.end())
				{
					update(1,0,n,pos,init((a[i]-(*prev(it)))/2));
				}
				else
				{
					update(1,0,n,pos,init((a[i]-(*prev(it)))/2));
					it++;
					int idnext = lower_bound(coord.begin(),coord.end(),(*it))-coord.begin();
					update(1,0,n,idnext,init(((*it)-a[i])/2));
				}
			}
			cout<<st[1].a[1][1]<<'\n';
		}
	}
}	
Compilation message (stderr)
fib.cpp: In function 'std::vector<int> getZeckendorf(vi)':
fib.cpp:46:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   for(int i=0;i<a.size();i++)
               ~^~~~~~~~~| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |