思路分析:
遗憾不知道矩阵的构造。线段树上比较水的矩阵。。。
M[x] = [1 A[x]]
[1 0 ]
就有
[ F[R] ] = M[R] * M[R-1] * ... * M[L+2] * [F[L+1]]
[F[R-1]] [ F[L] ] 。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define maxn 100005
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
#define mod 1000000007
using namespace std;
typedef long long LL;
LL save[maxn];
struct Matrix
{
LL data[2][2];
Matrix()
{
memset(data,0,sizeof data);
}
Matrix operator * (const Matrix &a)
{
Matrix temp;
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
temp.data[i][j] = ((data[i][k] * a.data[k][j]) + temp.data[i][j]) % mod;
return temp;
}
}tre[maxn<<2];
void pushup(int num)
{
tre[num]=tre[num<<1|1]*tre[num<<1];
}
void build(int num,int s,int e)
{
if(s==e)
{
tre[num].data[0][0]=1;
tre[num].data[0][1]=save[s];
tre[num].data[1][0]=1;
tre[num].data[1][1]=0;
return ;
}
int mid=(s+e)>>1;
build(lson);
build(rson);
pushup(num);
}
Matrix query(int num,int s,int e,int l,int r)
{
if(l<=s && r>=e)
{
return tre[num];
}
int mid=(s+e)>>1;
if(r<=mid)return query(lson,l,r);
else if(l>mid)return query(rson,l,r);
else return query(rson,l,r)*query(lson,l,r);//顺序 attention!
}
int main()
{
int T;
int n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&save[i]);
build(1,1,n);
while(m--)
{
int l,r;
scanf("%d%d",&l,&r);
if(r-l<2)printf("%d\n",save[r]);
else
{
Matrix temp=query(1,1,n,l+2,r);
LL ans=(temp.data[0][0]*save[l+1]+temp.data[0][1]*save[l])%mod;
printf("%lld\n",ans);
}
}
}
return 0;
}