ZOJ3772 - Calculate the Function(线段树+矩阵)
题目大意
给定一个序列A1 A2 .. AN 和M个查询
- 每个查询含有两个数 Li 和Ri.
- 查询定义了一个函数 Fi(x) 在区间 [Li, Ri] ∈ Z.
- Fi(Li) = ALi
- Fi(Li + 1) = A(Li + 1)
- 对于所有的x >= Li + 2, Fi(x) = Fi(x - 1) + Fi(x - 2) × Ax
求Fi(Ri)
题解
根据递推式可以构造一个矩阵:
继续展开,最终矩阵就是这个样子的了
因此每次查询就是求矩阵的连乘
普通的做法就是每查询一次线性计算一次上式,时间复杂度O(n),所以总的时间复杂度为O(m*n),显然要跪。。。线段树就很好的解决了这个问题,每个结点保存的都是一个矩阵,这样查询的时候就只需要O(logn)的时间了!
代码:
#include <iostream>
#include <string>
#include <cstring>
#include <stdio.h>
using namespace std;
#define maxn 100005
#define MOD 1000000007
#define lson l,m,s<<1
#define rson m+1,r,s<<1|1
typedef long long LL;
struct Matrix
{
LL mat[2][2];
int r;
void init(int n)
{
memset(mat,0,sizeof(mat));
r=n;
}
};
Matrix matrix_mul(Matrix a,Matrix b)
{
Matrix ans;
ans.init(a.r);
for(int i=0; i<a.r; i++)
for(int j=0; j<a.r; j++)
for(int k=0; k<a.r; k++)
if(a.mat[i][k]&&b.mat[k][j])
ans.mat[i][j]=(ans.mat[i][j]+a.mat[i][k]*b.mat[k][j])%MOD;
return ans;
}
LL a[maxn];
Matrix sum[maxn<<2];
void Pushup(int s)
{
sum[s]=matrix_mul(sum[s<<1|1],sum[s<<1]);
}
void build(int l,int r,int s)
{
sum[s].init(2);
if(l==r)
{
sum[s].mat[0][0]=sum[s].mat[1][0]=1;
sum[s].mat[0][1]=a[r];
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
Pushup(s);
}
Matrix query(int ql,int qr,int l,int r,int s)
{
if(ql<=l&&r<=qr) return sum[s];
int m=(l+r)>>1;
Matrix ret;
ret.init(2);
ret.mat[0][0]=ret.mat[1][1]=1;
if(qr>m) ret=matrix_mul(ret,query(ql,qr,rson));
if(ql<=m) ret=matrix_mul(ret,query(ql,qr,lson));
return ret;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++) scanf("%lld",&a[i]);
build(1,n,1);
while(m--)
{
int l,r;
scanf("%d%d",&l,&r);
if(l==r||(l+1)==r)
{
printf("%lld\n",a[r]);
continue;
}
Matrix ans=query(l+2,r,1,n,1);
//printf("%I64d %I64d\n",ans.mat[0][0],ans.mat[0][1]);
// printf("%I64d %I64d\n",ans.mat[1][0],ans.mat[1][1]);
printf("%lld\n",(ans.mat[0][0]*a[l+1]+ans.mat[0][1]*a[l])%MOD);
}
}
return 0;
}
ZOJ3772 - Calculate the Function(线段树+矩阵)的更多相关文章
- ZOJ 3772 Calculate the Function 线段树+矩阵
Calculate the Function Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %ll ...
- Z0J 3772 Calculate the Function 线段树+矩阵
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5235 这种题目居然没想到,一开始往矩阵快速幂想去了,因为之前跪了太多矩阵快速幂 ...
- Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)
题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...
- 线段树 + 矩阵 --- ZOJ 3772 Calculate the Function
Calculate the Function Problem's Link: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCod ...
- Codeforces Round #337 (Div. 2) D. Vika and Segments 线段树 矩阵面积并
D. Vika and Segments Vika has an infinite sheet of squared paper. Initially all squares are whit ...
- CF719E(线段树+矩阵快速幂)
题意:给你一个数列a,a[i]表示斐波那契数列的下标为a[i],求区间对应斐波那契数列数字的和,还要求能够维护对区间内所有下标加d的操作 分析:线段树 线段树的每个节点表示(f[i],f[i-1])这 ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)
线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵. #include<iostream> #include<cstdio> #include<cma ...
- CF718C Sasha and Array 线段树+矩阵加速
正解:线段树 解题报告: 传送门! 首先这种斐波拉契,又到了1e9的范围,又是求和什么的,自然而然要想到矩阵加速昂 然后这里主要是考虑修改操作,ai+=x如果放到矩阵加速中是什么意思呢QAQ? 那不就 ...
随机推荐
- android.content.Context 含义及使用
Context字面意思上下文,位于framework package的android.content.Context中,其实该类为LONG型,类似Win32中的Handle句柄,很多方法需要通过Con ...
- Android 下log的使用总结
Android 下log的使用总结 一:在源码开发模式下 1:包含头文件: #include <cutils/log.h> 2:定义宏LOG_TAG #define LOG_TAG &qu ...
- toad for sqlserver5.7
toad for sqlserver5.7 虽然SSMS很好很强大,不过有时候使用一些第三方工具可以使MSSQL DBA们更加的方便管理MSSQL toad for sqlserver5.7就是这样一 ...
- WIFI环境下Android手机和电脑通信
前面已经写过一篇java实现最基础的socket网络通信,这篇和之前那篇大同小异,只是将客户端代码移植到手机中,然后获取本机IP的方法略有不同. 先讲一下本篇中用到Android studio的使用吧 ...
- 学习Hadoop的资料
1)Cygwin相关资料 (1)Cygwin上安装.启动ssh服务失败.ssh localhost失败的解决方案 地址:http://blog.163.com/pwcrab/blog/static/1 ...
- 【转载】React初学者入门须知
http://www.oschina.net/news/75530/9-things-every-reactjs-beginner-should-know react.js入门学习 看了一遍,没什么特 ...
- SQL复制表及表结构
复制表结构和数据SQL语句 1:复制表结构及数据到新表 select * into 目的数据库名.dbo.目的表名 from 原表名 select * into my0735home.dbo.info ...
- android开发中eclipse里xml开发的自动提示和使用帮助快捷键提示
Eclipse Android 代码自动提示功能 Eclipse for android 设置代码提示功能 打 开 Eclipse 依次选择 Window > Preferences > ...
- Mysql 临时变量的 定义 和 赋值 Set 和 Into 赋值; Swith Mysql版本 Case When的用法
一:临时变量的定义和赋值 DECLARE spot SMALLINT; -- 分隔符的位置 DECLARE tempId VARCHAR(64); -- 循环 需要用到的临时的Cid DECLARE ...
- web页面性能测试
做Web开发,难免要对自己开发的页面进行性能检测,自己写工具检测,工作量太大.网上有几款比较成熟的检测工具,以下就介绍一下,与大家分享. 互联网现有工具 基于网页分析工具: 1. 阿里测 ...