ZOJ 2671 Cryptography(矩阵线段树)

原创 2015年07月07日 18:01:43

Description

Young cryptoanalyst Georgie is planning to break the new cipher invented by his friend Andie. To do this, he must make some linear transformations over the ring Zr = Z/rZ.

Each linear transformation is defined by 2×2 matrix. Georgie has a sequence of matrices A1 , A2 ,..., An . As a step of his algorithm he must take some segment Ai , Ai+1 , ..., Aj of the sequence and multiply some vector by a product Pi,j=Ai × Ai+1 × ... × Aj of the segment. He must do it for m various segments.

Help Georgie to determine the products he needs.

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 neach 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.

Sample

Input Output
3 4 4
0 1
0 0

2 1
1 2

0 0
0 2

1 0
0 2

1 4
2 3
1 3
2 2
0 2
0 0

0 2
0 1

0 1
0 0

2 1
1 2

题意:每次让你计算一个区间里(2*2)矩阵的值

分析:我们对于每个点建一个矩阵线段树,然后就是push一下,区间统计

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<string>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
const int INF=0x3f3f3f3f;
typedef long long LL;
int r,n,m;
const int maxn=30000+100;
LL a[maxn][2][2];
struct Matrix{
    LL mat[2][2];
    Matrix(){};
    Matrix(LL x1,LL x2,LL x3,LL x4)
    {
        mat[0][0]=x1;mat[0][1]=x2;
        mat[1][0]=x3;mat[1][1]=x4;
    }
}A[maxn<<2];
Matrix mult(Matrix m1,Matrix m2)
{
    Matrix ans;
    for(int i=0;i<2;i++)
    {
        for(int j=0;j<2;j++)
        {
            ans.mat[i][j]=0;
            for(int k=0;k<2;k++)
                ans.mat[i][j]=(ans.mat[i][j]+m1.mat[i][k]*m2.mat[k][j])%r;
        }
    }
    return ans;
}
void build(int rs,int l,int r)
{
    if(l==r)
    {
        A[rs]=Matrix(a[l][0][0],a[l][0][1],a[l][1][0],a[l][1][1]);
        return ;
    }
    int mid=(l+r)>>1;
    build(rs<<1,l,mid);
    build(rs<<1|1,mid+1,r);
    A[rs]=mult(A[rs<<1],A[rs<<1|1]);
}
Matrix query(int x,int y,int l,int r,int rs)
{
    if(l>=x&&r<=y)
        return A[rs];
    int mid=(l+r)>>1;
    if(y<=mid) return query(x,y,l,mid,rs<<1);
    if(x>mid) return query(x,y,mid+1,r,rs<<1|1);
    return mult(query(x,mid,l,mid,rs<<1),query(mid+1,y,mid+1,r,rs<<1|1));
}
int main()
{
    int x,y;
    int cas=0;
    while(~scanf("%d%d%d",&r,&n,&m))
    {
        REPF(i,1,n)
           scanf("%lld%lld%lld%lld",&a[i][0][0],&a[i][0][1],&a[i][1][0],&a[i][1][1]);
        build(1,1,n);
        while(m--)
        {
            if(cas) puts("");
            scanf("%d%d",&x,&y);cas++;
            Matrix ans=query(x,y,1,n,1);
            printf("%lld %lld\n%lld %lld\n",ans.mat[0][0],ans.mat[0][1],ans.mat[1][0],ans.mat[1][1]);
        }
    }
}


zoj 2671 Cryptography(矩阵相乘+线段树)

Cryptography Time Limit: 5 Seconds      Memory Limit: 32768 KB Young cryptoanalyst Georgie ...
  • WEYuLi
  • WEYuLi
  • 2014年01月22日 16:13
  • 629

zoj3772--【水题】线段树区间查询+矩阵乘法

思路来源:http://blog.csdn.net/u013654696/article/details/23037407#comments 【思路不是自己的,但代码是自己敲的,由于伦家不懂】...
  • u011652573
  • u011652573
  • 2014年04月08日 21:24
  • 694

ZOJ 2671 (线段树+矩阵乘法)

这题着实是锻炼线段树的一个好题,纯模板题但是加上了一点其他的东西,细节很多 细节一:格式错误,每两个一大组数据和之间需要有有一个换行。 细节二:每两个输出之间有一个换行 细节三:每次需要清空存储...
  • yxm980918
  • yxm980918
  • 2017年07月06日 21:23
  • 75

ZOJ 2671 线段树 + 矩阵区间乘积

传送门 : zoj 2671summary 下次, 线段树不用cin, cout了有毒啊 AC code:#include #include #include using namespace st...
  • ADjky
  • ADjky
  • 2016年12月10日 23:11
  • 323

主席树/函数式线段树/可持续化线段树 POJ_2104,BZOJ_1901,ZOJ_2112

明天就要去上海了,我还这么狗,感觉自己萌萌哒。     这几天学主席树,熬夜了三次,每次都到三四点,但是都不困,已然爱上深夜打代码。     主席树是一种神奇的数据结构,它将线段树和前缀和...
  • u014610925
  • u014610925
  • 2014年12月03日 14:02
  • 826

树套树(线段树套平衡树)—— ZOJ 2112 Dynamic Rankings

对应题目链接:点击打开链接 Dynamic Rankings Time Limit: 10000MS   Memory Limit: 32768KB   64bit IO Format: ...
  • u013351484
  • u013351484
  • 2015年11月22日 11:48
  • 881

poj 2528 Mayor's posters(线段树区间覆盖、离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 49385   Accepted:...
  • aaaaacmer
  • aaaaacmer
  • 2015年07月28日 11:12
  • 704

ZOJ(矩阵乘法+线段树)

题意:先给出一序列数字,编号从1到n,然后再给出L
  • u010880589
  • u010880589
  • 2014年04月07日 21:09
  • 366

ZOJ 3772 矩阵 + 线段树

传送门 :zoj 3772 题解 还是节点存储矩阵, 不过这题各哥节点基矩阵不同, 所以要考虑方向,wa + 3, pe + 1 AC code:#include #include #includ...
  • ADjky
  • ADjky
  • 2016年12月10日 18:41
  • 178

hdu 1542 扫描线+线段树求矩阵面积并

这几天想啃啃树,无意中找到了这个题,一方面练习一下线段树,另一方面学习一下离散化和扫描线的技巧。       首先,离散化是必要的,因为x,y       显然,离散化的数据不会有重复,这里要介绍...
  • EzCUfST
  • EzCUfST
  • 2015年08月01日 19:54
  • 873
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ZOJ 2671 Cryptography(矩阵线段树)
举报原因:
原因补充:

(最多只允许输入30个字)