题目来源:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1671
代码如下:
typedef long long LL ; const double EPS = 1e-12; const int Max_N = 30005; int Mod; struct Mat{ int elem[3][3]; Mat(){ memset(elem,0, sizeof(elem)); } Mat operator * ( Mat m){ Mat s; for(int i=1; i<=2; i++){ for(int j=1; j<=2; j++){ for( int k=1; k<=2 ; k++){ s.elem[i][j]= (s.elem[i][j] + elem[i][k]*m.elem[k][j]) % Mod; } } } return s; } void read(){ scanf("%d%d%d%d",&elem[1][1], &elem[1][2], &elem[2][1], &elem[2][2]); } void output(){ for(int i=1; i<=2; i++) printf("%d %d ",elem[i][1] % Mod, elem[i][2] % Mod); } }; Mat sum[Max_N <<2]; Mat data[Max_N]; //从下向上 更新值 void push_up(int root){ sum[root] = sum[root<<1] * sum[root<<1|1]; } // 建树 , 从根节点出发, 根节点从1开始 void make_tree(int L, int R, int root){ if(L == R){ sum[root]= data[L]; return ; } int mid=(L + R)>>1; make_tree(L, mid, root<<1); make_tree(mid+1, R, root<<1|1); push_up(root); } //查询, Mat query(int l, int r, int L, int R, int root){ if(l<=L && R<=r) return sum[root]; int mid=(L + R)>>1; if(mid >= r) return query(l, r, L, mid, root<<1); else if(mid< l) return query(l, r, mid+1, R, root<<1|1); else return query(l,r, L, mid, root<<1) * query(l, r, mid+1, R, root<<1|1); } int main(){ int n, m, x, y ; int count =1; while(scanf("%d%d%d",&Mod,&n,&m)!= EOF){ if(count > 1){ puts(""); } count++; for(int i=1; i<=n; i++){ data[i].read(); } make_tree(1,n,1); for(int i=1; i<=m; i++){ scanf("%d%d",&x,&y); Mat res=query(x,y, 1,n,1); res.output(); if(i!=m) puts(""); } } return 0; }