ZOJ 2671 Cryptography 矩阵乘法+线段树
Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu
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 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.
Sample
| Input | Output |
3 4 4 |
0 2 |
题意是给出n个矩阵,编号是从1到n,再给m个查询,每个查询给定l和r,输出第l个矩阵连成到第r个矩阵的积,每次乘法操作后都要对每个数对r求余。
思路很容易想到用线段树,保存下中间的变量,下次查询再需要用到的时候可以直接返回这一个结果,时间复杂度o(mlogn)。网络上很多这题题解了,那我就贴一个zkw版的吧。需要注意的是,矩阵乘法不满足交换律,只能第l个乘第l+1个一直乘到第r个,但是zkw的线段树,是先遇到第l个和第r个,然后遇到第l+1和r-1、l+2和r-2一直到l跟r在同一层,所以顺序要有点改变,我使用了vector,但相比起传统线段树还是时间还是少了不少。
代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
const int N = ;
int r,n,m,M;
struct _matrix
{
int mat[][];
_matrix operator * (const _matrix &b) const {
_matrix res;
for(int i=;i<;++i)
for(int j=;j<;++j)
{
int sum=;
for(int k=;k<;++k) sum+=mat[i][k]*b.mat[k][j];
res.mat[i][j]=sum%r;
}
return res;
}
_matrix operator *= (const _matrix &b) {
return *this = (*this) * b;
}
void clear() {memset(mat,,sizeof(mat));for(int i=;i<;++i) mat[i][i]=;}
void in() {scanf("%d%d%d%d",&mat[][],&mat[][],&mat[][],&mat[][]);}
void out() {printf("%d %d\n%d %d\n",mat[][],mat[][],mat[][],mat[][]);}
};
_matrix res[*N];
void build(int x)
{
_matrix tmp;
tmp.in();
for(x+=M;x;x>>=) res[x] *= tmp;
}
vector<int> vi;
_matrix query(int x,int y)
{
_matrix ans;
ans.clear();
vi.clear();
int l=x+M-,r=y+M+;
for(x=l,y=r;x^y^;x>>=,y>>=)//注意顺序
if(~x&) ans*=res[x^];
for(x=l,y=r;x^y^;x>>=,y>>=)
if(y&)
vi.push_back(y^);
for(int i=vi.size()-;i>=;--i)
ans *= res[vi[i]];
return ans;
}
bool fir2=;
void run()
{
if(fir2) fir2=;
else puts("");
for(M=;M<=n;M+=M);
for(int i=;i<=M+n;++i) res[i].clear();
for(int i=;i<=n;++i)
build(i);
int l,r;
bool fir=;
while(m--)
{
if(fir) fir=;
else puts("");
scanf("%d%d",&l,&r);
query(l,r).out();
}
}
int main()
{
while(scanf("%d%d%d",&r,&n,&m)!=EOF)
run();
return ;
}
ZOJ 2671 Cryptography 矩阵乘法+线段树的更多相关文章
- THUSCH 2017 大魔法师(矩阵乘法+线段树)
题意 https://loj.ac/problem/2980 思路 区间修改考虑用线段树维护.由于一段区间的 \(A,B,C\) 可以表示成由原来的 \(A,B,C\) 乘上带上系数再加上某一个某个常 ...
- Luogu P4643 【模板】动态dp(矩阵乘法,线段树,树链剖分)
题面 给定一棵 \(n\) 个点的树,点带点权. 有 \(m\) 次操作,每次操作给定 \(x,y\) ,表示修改点 \(x\) 的权值为 \(y\) . 你需要在每次操作之后求出这棵树的最大权独立集 ...
- HDU 6155 Subsequence Count(矩阵乘法+线段树+基础DP)
题意 给定一个长度为 \(n\) 的 \(01\) 串,完成 \(m\) 种操作--操作分两种翻转 \([l,r]\) 区间中的元素.求区间 \([l,r]\) 有多少个不同的子序列. \(1 \le ...
- HDU 3074.Multiply game-区间乘法-线段树(单点更新、区间查询),上推标记取模
Multiply game Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- ZOJ 3772 Calculate the Function 线段树+矩阵
Calculate the Function Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %ll ...
- codeforces750E New Year and Old Subsequence 矩阵dp + 线段树
题目传送门 思路: 先看一个大牛的题解 题解里面对矩阵的构造已经写的很清楚了,其实就是因为在每个字符串都有固定的很多中状态,刚好可以用矩阵来表达,所以$(i,j)$这种状态可以通过两个相邻的矩阵的$m ...
- HDU 6155 Subsequence Count(矩阵 + DP + 线段树)题解
题意:01串,操作1:把l r区间的0变1,1变0:操作2:求出l r区间的子序列种数 思路:设DP[i][j]为到i为止以j结尾的种数,假设j为0,那么dp[i][0] = dp[i - 1][1] ...
- ZOJ 3911 Prime Query(线段树)
Prime Query Time Limit: 1 Second Memory Limit: 196608 KB You are given a simple task. Given a s ...
- ZOJ 1610 Count the Color(线段树区间更新)
描述Painting some colored segments on a line, some previously painted segments may be covered by some ...
随机推荐
- 开始使用gradle
前提配置gradle环境 每个gradle构建都是以一个脚本开始的.gradle构建默认的名称为build.gradle.当在shell中执行gradle命令时,gradle会去寻找为build.gr ...
- python 基础 6.1 异常处理方法
一. Excepthion 异常类 Excepthion 是所有的异常基础类(),对于python 的标准异常,我们列出如下,以做参考: 异常名称 ...
- spirng boot资料
这里有个srping boot 各种整合的资料 https://blog.csdn.net/Winter_chen001/article/details/80537829 SpringBoot入门总结 ...
- 基于EasyNVR+EasyDSS H5视频直播二次开发实现业务需求:直接使用播放页面
之前的"网页直播.微信直播技术解决方案:EasyNVR与EasyDSS流媒体服务器组合之区分不同场景下的easynvr"有介绍一些功能.由于客户需求,我们定制一下功能.给该套方案添 ...
- EasyNVR H5直播流媒体解决方案前端构建之:如何播放自动适配RTMP/HLS直播播放
之前在进行EasyNVR多屏开发的时候,由于多屏功能不需要在手机端展示出来(pc多播放为RTMP,手机端播放为HLS),因此只注意到了引用videojs来进行rtmp的播放.由于不同项目需求不同,对h ...
- 基于传统IPC基础上的RTMP互联网推流摄像机方案设计
在我之前的一篇博客<EasyRTMP内置进入摄像机中实现网络推流直播摄像机的功能>中,我阐述了一种将RTMP推流内置到摄像机系统内部,实现安防摄像机转互联网直播的RTMP推流摄像机功能,如 ...
- 不依赖外部js es 库 实现 点击内容 切换
<!DOCTYPE html> <html lang="zh-cmn-Hans"> <head> <meta http-equiv=&qu ...
- Regularization: how complicated the model is? Regularization, measures complexity of model 使预测准确、平稳 predictive stable
http://www.kdd.org/kdd2016/papers/files/rfp0697-chenAemb.pdf https://homes.cs.washington.edu/~tqchen ...
- 微软Azure区块链开发工具包三大功能详解
2018年11月15日,微软宣布了Azure区块链开发工具包,它基于微软的无服务器技术构建,并且利用微软和第三方SaaS,完美集成了区块链.该工具包扩展了微软的区块链开发模板和Azure Blockc ...
- linux rsyncserver文件同步
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zqtsx/article/details/24254651 [root@zqtsx]# rpm -q ...