1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| # include <bits/stdc++.h> using namespace std; typedef long long int LL;
const int N = 100000+7; const int M = 2; const int MOD = 1e9+7;
struct Matrix{ LL m[M][M]; void clear0(){ for(int i=0;i<M;i++) for(int j=0;j<M;j++) m[i][j]=0; } void clearE(){ for(int i=0;i<M;i++) for(int j=0;j<M;j++) m[i][j]=(i==j); }
};
Matrix operator * (Matrix a,Matrix b){ Matrix c; c.clear0();
for(int k=0;k<M;k++){ for(int i=0;i<M;i++){ for(int j=0;j<M;j++){ c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j]+MOD)%MOD; } } } return c; }
struct node{ Matrix a; int l,r; }tree[N<<2]; int w[N];
# define ll (rt<<1) # define rr (rt<<1|1) # define mid ((r+l)>>1)
void pushup(int rt){ tree[rt].a=tree[ll].a*tree[rr].a; }
void build(int rt,int l,int r){ tree[rt].l=l,tree[rt].r=r; if(l==r){ tree[rt].a.m[0][0]=1 ,tree[rt].a.m[0][1]=1; tree[rt].a.m[1][0]=w[l],tree[rt].a.m[1][1]=0; return ; } build(ll,l,mid); build(rr,mid+1,r); pushup(rt); }
Matrix query(int rt,int L,int R){ if(L<=tree[rt].l&&tree[rt].r<=R) return tree[rt].a;
Matrix ans,b;ans.clearE(); int md = (tree[rt].l+tree[rt].r)>>1; if(L<=md) b=query(ll,L,R),ans=ans*b; if(R> md) b=query(rr,L,R),ans=ans*b; return ans; }
Matrix a,b;
void ask(int l,int r){ if(l==r||l+1==r){ printf("%d\n",w[r]); return ; }
a.m[0][0]=w[l+1],a.m[0][1]=w[l]; a.m[1][0]=0 ,a.m[1][1]=0; b=query(1,l+2,r); b=a*b; printf("%d\n",b.m[0][0]);
return ; }
int main(){ int _; scanf("%d",&_); while(_--){ int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&w[i]); }
build(1,1,n);
int l,r; while(m--){ scanf("%d%d",&l,&r); ask(l,r); } } return 0; }
|