ZOJ_2671_Cryptography_线段树

来源:互联网 发布:ubuntu怎么安装iso软件 编辑:程序博客网 时间:2024/04/30 02:36

昨天搞数模,每个题都跟打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 from0 to r - 1 each, describe matrices. Blocks are separated with blank lines. They are followed bym 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 from0 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 30010int 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);elsereturn 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;}


0 0