昨天搞数模,每个题都跟打ACM一样。。
题意:
给一个长为n的2*2方阵的一维数组,询问m次,每次给出l,r,询问矩阵从第l个乘到第r个的积是多少
Input
There are several test cases in the input. The first line of each case contains r ( 1 <= r <= 10,000), n ( 1 <= n <= 30,000) and m ( 1 <= m <= 30,000). Next n blocks of two lines, containing two integer numbers ranging from 0 to r - 1 each, describe matrices. Blocks are separated with blank lines. They are followed by m pairs of integer numbers ranging from 1 to n each that describe segments, products for which are to be calculated.There is an empty line between cases.
Output
Print m blocks containing two lines each. Each line should contain two integer numbers ranging from 0 to r - 1 and define the corresponding product matrix.
There should be an empty line between cases.
Separate blocks with an empty line.
裸的线段树,利用的核心是二分算法。现在数据结构用OO写挺不下来怎么办
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
using namespace std;
#define mxn 30010
int r,n,m;
class matrix{
private:
int a[2][2];
public:
matrix(){}
matrix(int m,int n,int p,int q){
a[0][0]=m,a[0][1]=n;
a[1][0]=p,a[1][1]=q;
}
void read(){
scanf("%d%d%d%d",&a[0][0],&a[0][1],&a[1][0],&a[1][1]);
}
void print(){
printf("%d %d\n%d %d\n",a[0][0],a[0][1],a[1][0],a[1][1]);
}
matrix operator * (const matrix& in)const{
matrix ret;
for(int i=0;i<2;++i)
for(int j=0;j<2;++j)
ret.a[i][j]=(a[i][0]*in.a[0][j]%r+a[i][1]*in.a[1][j]%r)%r;
return ret;
}
}M[mxn];
class node{
public:
int ll,rr;
matrix pro;
};
class segment_tree{
private:
node nd[mxn<<2];
void merge(int id){
int ls=id<<1,rs=ls|1;
nd[id].pro=nd[ls].pro*nd[rs].pro;
}
public:
void build(int l,int r,int id){
nd[id].ll=l;
nd[id].rr=r;
if(l==r){
nd[id].pro=M[l];
return;
}
int m=(l+r)>>1,ls=id<<1,rs=ls|1;
build(l,m,ls);
build(m+1,r,rs);
merge(id);
}
matrix find(int l,int r,int id){
if(l==nd[id].ll&&r==nd[id].rr)
return nd[id].pro;
int m=(nd[id].ll+nd[id].rr)>>1,ls=id<<1,rs=ls|1;
if(r<=m) return find(l,r,ls);
else if(l>m) return find(l,r,rs);
else return find(l,m,ls)*find(m+1,r,rs);
}
}Tree;
int main(){
bool first=true;
while(scanf("%d%d%d",&r,&n,&m)!=EOF){
if(!first) puts("");
first=false;
for(int i=0;i<n;++i) M[i].read();
Tree.build(0,n-1,1);
int l,r;
matrix ans;
for(int i=0;i<m;++i){
scanf("%d%d",&l,&r);
ans=Tree.find(l-1,r-1,1);
ans.print();
if(i!=m-1) puts("");
}
}
return 0;
}