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(线段树+矩阵乘法)

【题目大意】:给出数字范围r,n个矩阵,和m个查询,每个查询第i个矩阵到第j个矩阵的乘积,且乘后不超过r。 【解题思路】:利用线段树进行优化。   原来case与case直接的矩阵也要有空...

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

Cryptography Time Limit: 5 Seconds      Memory Limit: 32768 KB Young cryptoanalyst Georgie ...

【ZOJ】2671 Cryptography 线段树

传送门:【ZOJ】2671 Cryptography 题目分析:线段树水题。

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

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

线段树模板 zoj1128

ZOJ 3772 Calculate the Function [线段树+矩阵乘法]【思维?】

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3772 ————————————————————————————...

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

思路来源:http://blog.csdn.net/u013654696/article/details/23037407#comments 【思路不是自己的,但代码是自己敲的,由于伦家不懂】

ZOJ 3772 矩阵 + 线段树

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

zoj 3772 Calculate the Function(线段树+矩阵乘法)

Calculate the Function Time Limit: 2 Seconds      Memory Limit: 65536 KB You are given a ...

zoj 3772 Calculate the Function(矩阵+线段树)

开始以为是数学递推找规律,尝试了以后发现这条路走不通。 考虑到既有加又有乘,可能就是我们熟悉的矩阵。然后想试着用逆矩阵的形式求解,发现会出现a[x] 为分母的情况。所以最后使用线段树来求解区间的矩阵...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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