哈工大 3772 矩阵+线段树

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3772

   ac 代码

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #define mod 1000000007
 5 using namespace std;
 6 
 7 struct node{long long mat[2][2];} a[100002];
 8 struct node2{int l,r; node matrix;} tree[440004];  //树的节点
 9 
10 node mul(node a,node b)  // 两个矩阵 相乘 返回 node型
11 {
12     node c;
13     int i,j,k;
14     for(i=0;i<2;i++)
15     {
16         for(j=0;j<2;j++)
17         {
18             c.mat[i][j]=0;
19             for(k=0;k<2;k++)
20             {
21                 c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%mod;
22             }
23             //c.mat[i][j]=c.mat[i][j]%mod;
24         }
25     }
26     return c;
27 }
28 
29 node2 build(int l,int r,int k)  // tree[k]  a[l]***  a[r]
30 {
31     tree[k].l=l;
32     tree[k].r=r;
33     if(l==r)
34     {
35        tree[k].matrix.mat[0][0]=a[l].mat[0][0];
36        tree[k].matrix.mat[0][1]=a[l].mat[0][1];
37        tree[k].matrix.mat[1][0]=a[l].mat[1][0];
38        tree[k].matrix.mat[1][1]=a[l].mat[1][1];
39        return tree[k];
40     }
41     int mid;
42     mid=(l+r)/2;
43     build(l,mid,k*2);
44     build(mid+1,r,k*2+1);
45     tree[k].matrix=mul(tree[k*2].matrix,tree[k*2+1].matrix);
46 }
47 
48 node ans(int x,int y,int k)
49 {
50     if(tree[k].l>=x&&tree[k].r<=y)
51         return tree[k].matrix;
52 
53     int mid;
54     mid=(tree[k].l+tree[k].r)/2;
55     if(y<=mid)
56         return ans(x,y,k*2);
57     else if(x>=mid+1)
58         return ans(x,y,k*2+1);
59     return mul(ans(x,mid,k*2),ans(mid+1,y,k*2+1));
60 }
61 
62 void qus(int l,int r)//
63 {
64     if(r==l||r-1==l)
65     {
66         printf("%lld\n",a[r].mat[1][0]);
67         return ;
68     }
69     node temp;
70     temp=ans(l+2,r,1);
71     long long final1;
72 
73     final1=(a[l+1].mat[1][0]*temp.mat[0][0]+a[l].mat[1][0]*temp.mat[1][0])%mod;
74     printf("%lld\n",final1);
75 }
76 
77 int main()
78 {
79     int t,n,m,l,r;
80     long long x;
81     scanf("%d",&t);
82     while(t--)
83     {
84         scanf("%d%d",&n,&m);
85         for(int i=1;i<=n;i++)
86         {
87             scanf("%lld",&x);
88             a[i].mat[0][0]=1; a[i].mat[0][1]=1;
89             a[i].mat[1][0]=x; a[i].mat[1][1]=0;
90         }
91         build(1,n,1);
92         while(m--)
93         {
94             scanf("%d%d",&l,&r);
95             qus(l,r);
96         }
97     }
98     return 0;
99 }

 

posted @ 2014-04-07 18:44  galaxy77  阅读(128)  评论(0编辑  收藏  举报