思路来源:http://blog.csdn.net/u013654696/article/details/23037407#comments
总结:(ー`´ー)敲了一天,开始是体会错公式了,结果乘多了最后两个矩阵,后来又忘记取余了~~~这个逗比的教训告诉我们,做事要细心~~还有代码写矬了果断删掉重写!
下面上AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; #define maxn 100010 #define mod 1000000007 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 long long fun[maxn]; long long num[maxn<<2]; int n, m; class matrix{ public: long long mat[2][2]; matrix() { mat[0][0] = mat[1][1] = 1; mat[0][1] = mat[1][0] = 0; } matrix(long long a) { mat[0][0] = mat[1][0] = 1; mat[0][1] = a; mat[1][1] = 0; } matrix operator*(const matrix& m)const { matrix tmp; for(int i = 0; i < 2; i++) for(int j = 0; j < 2; j++){ tmp.mat[i][j] = 0; for(int k = 0; k < 2; k++) { tmp.mat[i][j] += mat[i][k] * m.mat[k][j] % mod; tmp.mat[i][j] %= mod; } } return tmp; } }; matrix sgt[maxn<<2]; void pushup(int rt) { sgt[rt] = sgt[rt<<1|1] * sgt[rt<<1]; //注意矩阵乘的方向!! } void build(int l, int r, int rt) { if(l == r) { sgt[rt] = matrix(fun[l]); return; } int m = (l+r)>>1; build(lson); build(rson); pushup(rt); } matrix query(int l, int r, int rt, int L, int R) { if(L <= l && r <= R) { return sgt[rt]; } int m = (l + r)>>1; matrix tmp; if(m < R) tmp = tmp * query(rson, L, R); //注意矩阵乘的方向!! if(L <= m) tmp = tmp * query(lson, L, R); return tmp; } long long result(int l, int r, int rt, int L, int R) { if(R - L < 2) //判断区间长度,小于等于二的直接输出右区间; { return fun[R]; } matrix tmp; tmp = query(l, r, rt, L+2, R); long long a; a = tmp.mat[0][0] * fun[L+1] + tmp.mat[0][1] * fun[L]; a %= mod; return a; } int main() { int T; cin>>T; while(T--) { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) scanf("%d", &fun[i]); build(1, n, 1); long long a; for(int i = 0; i < m; i++) { a = 0; int c, d; scanf("%d%d", &c, &d); a = result(1, n, 1, c, d); printf("%d ",a); } } return 0; }
作者:u011652573 发表于2014-4-8 21:24:15 原文链接
阅读:54 评论:0 查看评论