zoj 3772 Calculate the Function

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5235

这道题需要构造矩阵:F(X)=F(X-1)+F(X-2)*A(X)转化为F(X)*A(X+2)+F(X+1)=F(X+2),然后在构造矩阵

{1, A[x]}  {F(x+1)}  {F(X+2)}

{1,    0 }*{F(X)    }={F(X+1)}

然后用线段数维护乘号左边的乘积;

  1 #include <cstdio>

  2 #include <cstring>

  3 #include <algorithm>

  4 #define maxn 101000

  5 using namespace std;

  6 const int mod=1000000007;

  7 

  8 int t,a[maxn*10],n,m;

  9 int l,r;

 10 struct matrix

 11 {

 12     long long a[4][4];

 13 };

 14 

 15 struct node 

 16 {

 17     int l;

 18     int r;

 19     matrix c;

 20 } tree[maxn*4];

 21 

 22 matrix multi(matrix x,matrix y)

 23 {

 24     matrix temp;

 25     for(int i=1; i<=2; i++)

 26     {

 27         for(int j=1; j<=2; j++)

 28         {

 29             temp.a[i][j]=0;

 30             for(int k=1; k<=2; k++)

 31             {

 32                 temp.a[i][j]=(x.a[i][k]*y.a[k][j]+temp.a[i][j])%mod;

 33             }

 34         }

 35     }

 36     return temp;

 37 }

 38 

 39 matrix build(int i,int l,int r)

 40 {

 41     tree[i].l=l;

 42     tree[i].r=r;

 43     if(l==r)

 44     {

 45         tree[i].c.a[1][1]=1;

 46         tree[i].c.a[1][2]=a[l];

 47         tree[i].c.a[2][1]=1;

 48         tree[i].c.a[2][2]=0;

 49         return tree[i].c;

 50     }

 51     int mid=(l+r)>>1;

 52     build(i<<1,l,mid);

 53     build(i<<1|1,mid+1,r);

 54     tree[i].c=multi(tree[i<<1|1].c,tree[i<<1].c);

 55     return tree[i].c;

 56 }

 57 

 58 matrix search1(int i,int l,int r)

 59 {

 60     if(tree[i].l==l&&tree[i].r==r)

 61     {

 62         return tree[i].c;

 63     }

 64     int mid=(tree[i].l+tree[i].r)>>1;

 65     if(r<=mid)

 66     {

 67         return search1(i<<1,l,r);

 68     }

 69     else if(l>mid)

 70     {

 71         return search1(i<<1|1,l,r);

 72     }

 73     else

 74     {

 75         return multi(search1(i<<1|1,mid+1,r),search1(i<<1,l,mid));

 76     }

 77 }

 78 int main()

 79 {

 80     scanf("%d",&t);

 81     while(t--)

 82     {

 83         scanf("%d%d",&n,&m);

 84         for(int i=1; i<=n; i++)

 85         {

 86             scanf("%d",&a[i]);

 87         }

 88         build(1,1,n);

 89         while(m--)

 90         {

 91             scanf("%d%d",&l,&r);

 92             if(r-l>=2)

 93             {

 94                 matrix tm,ans;

 95                 tm.a[1][1]=a[l+1];

 96                 tm.a[2][1]=a[l];

 97                 ans=multi(search1(1,l+2,r),tm);

 98                 printf("%lld\n",ans.a[1][1]);

 99             }

100             else printf("%d\n",a[r]%mod);

101         }

102     }

103     return 0;

104 }
View Code

 

你可能感兴趣的:(function)