之前板刷了很多的矩阵的题目。结果心中就有了一个很错误的想法。
就是矩阵的题目都是用来高次幂运算的。
今天看了这道题目,一开始感觉是矩阵,后来看看了,感觉不是矩阵,就放弃了。
后来放学的时候,SCF跟我说这道题目是线段树+矩阵。
我就又开始想了这道题目。
后来仔细想了想发现,原来是线段树预处理矩阵,然后每次询问O(log(n))。
又学到了一招,真棒
#include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <stack> #include <map> using namespace std; #define LL long long #define MOD 1000000007 struct matrix { LL mat[3][3]; }A[110000],B; struct list { matrix a; int l; int r; }node[110000*4]; matrix mul(matrix a,matrix b) { matrix c; int i,j,k; for(i=1;i<=2;i++) { for(j=1;j<=2;j++) { c.mat[i][j]=0; for(k=1;k<=2;k++) { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; } c.mat[i][j]=c.mat[i][j]%MOD; } } return c; } matrix build(int l,int r,int st) { if(l==r) { node[st].l=l; node[st].r=r; node[st].a=A[l]; return node[st].a; } matrix a,b; int mid=(l+r)/2; a=build(l,mid,st*2); b=build(mid+1,r,st*2+1); node[st].l=l; node[st].r=r; node[st].a=mul(b,a); return node[st].a; } matrix ans(int x,int y,int st) { int l=node[st].l; int r=node[st].r; if(x<=l&&r<=y) { return node[st].a; } if(x>r||y<l) { matrix a; a.mat[1][1]=1;a.mat[1][2]=0; a.mat[2][2]=1;a.mat[2][1]=0; return a; } int mid=(l+r)/2; if(y<=mid)return ans(x,y,st*2); else if(x>mid)return ans(x,y,st*2+1); else { return mul(ans(x,y,st*2+1),ans(x,y,st*2)); } } void qus(int x,int y) { if(x==y||x==y-1) { cout<<A[y].mat[1][2]<<endl; return; } matrix C; B.mat[1][1]=A[x+1].mat[1][2]; B.mat[1][2]=0; B.mat[2][1]=A[x].mat[1][2]; B.mat[2][2]=0; C=ans(x+2,y,1); C=mul(C,B); cout<<C.mat[1][1]<<endl; } int main() { int T,x,n,m,i,y; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%d",&x); A[i].mat[1][1]=1; A[i].mat[1][2]=x; A[i].mat[2][1]=1; A[i].mat[2][2]=0; } build(1,n,1); while(m--) { scanf("%d%d",&x,&y); qus(x,y); } } return 0; }