我们考虑线性代数上面的矩阵知识

啊呸,是基础数学

斐波那契的矩阵就不讲了

定义矩阵 \(f_x\) 是第 \(x\) 项的斐波那契矩阵

因为

\(f_i * f_j = f_{i+j}\)

然后又因为 \(\texttt{AB+AC=A(B+C)}\)

所以 \(\sum_{i=l}^{r} f(a_i+x) = f(x)\sum_{i=l}^{r} f(a_i)\)

线段树板子题,维护一个矩阵,这题没了

// by Isaunoya
#include <bits/stdc++.h>
using namespace std; #define rep(i, x, y) for (register int i = (x); i <= (y); ++i)
#define Rep(i, x, y) for (register int i = (x); i >= (y); --i)
#define int long long const int _ = 1 << 21;
struct I {
char fin[_], *p1 = fin, *p2 = fin;
inline char gc() {
return (p1 == p2) && (p2 = (p1 = fin) + fread(fin, 1, _, stdin), p1 == p2) ? EOF : *p1++;
}
inline I& operator>>(int& x) {
bool sign = 1;
char c = 0;
while (c < 48) ((c = gc()) == 45) && (sign = 0);
x = (c & 15);
while ((c = gc()) > 47) x = (x << 1) + (x << 3) + (c & 15);
x = sign ? x : -x;
return *this;
}
inline I& operator>>(double& x) {
bool sign = 1;
char c = 0;
while (c < 48) ((c = gc()) == 45) && (sign = 0);
x = (c - 48);
while ((c = gc()) > 47) x = x * 10 + (c - 48);
if (c == '.') {
double d = 1.0;
while ((c = gc()) > 47) d = d * 0.1, x = x + (d * (c - 48));
}
x = sign ? x : -x;
return *this;
}
inline I& operator>>(char& x) {
do
x = gc();
while (isspace(x));
return *this;
}
inline I& operator>>(string& s) {
s = "";
char c = gc();
while (isspace(c)) c = gc();
while (!isspace(c) && c != EOF) s += c, c = gc();
return *this;
}
} in;
struct O {
char st[100], fout[_];
signed stk = 0, top = 0;
inline void flush() {
fwrite(fout, 1, top, stdout), fflush(stdout), top = 0;
}
inline O& operator<<(int x) {
if (top > (1 << 20)) flush();
if (x < 0) fout[top++] = 45, x = -x;
do
st[++stk] = x % 10 ^ 48, x /= 10;
while (x);
while (stk) fout[top++] = st[stk--];
return *this;
}
inline O& operator<<(char x) {
fout[top++] = x;
return *this;
}
inline O& operator<<(string s) {
if (top > (1 << 20)) flush();
for (char x : s) fout[top++] = x;
return *this;
}
} out;
#define pb emplace_back
#define fir first
#define sec second template < class T > inline void cmax(T & x , const T & y) {
(x < y) && (x = y) ;
}
template < class T > inline void cmin(T & x , const T & y) {
(x > y) && (x = y) ;
} const int mod = 1e9 + 7 ;
const int maxn = 1e5 + 51 ;
struct matrix {
int a[3][3] ;
matrix () {
rep(i , 1 , 2) rep(j , 1 , 2) a[i][j] = 0 ;
}
void clr() {
rep(i , 1 , 2) rep(j , 1 , 2) a[i][j] = 0 ;
rep(i , 1 , 2) a[i][i] = 1 ;
}
bool empty() {
if(a[1][1] ^ 1) return false ;
if(a[1][2] || a[2][1]) return false ;
if(a[2][2] ^ 1) return false ;
return true ;
}
matrix operator * (const matrix & other) const {
matrix res ;
rep(i , 1 , 2) rep(j , 1 , 2) {
res.a[i][j] = 0 ;
rep(k , 1 , 2) res.a[i][j] = (res.a[i][j] + a[i][k] * other.a[k][j]) % mod ;
}
return res ;
}
matrix operator + (const matrix & other) const {
matrix res ;
rep(i , 1 , 2) rep(j , 1 , 2) res.a[i][j] = (a[i][j] + other.a[i][j] >= mod) ? a[i][j] + other.a[i][j] - mod : a[i][j] + other.a[i][j] ;
return res ;
}
} ;
matrix qwq ;
matrix qpow(matrix a , int k) {
matrix res = a ; -- k ;
for( ; k ; a = a * a , k >>= 1)
if(k & 1) res = res * a ;
return res ;
}
int n , m ;
int a[maxn] ;
matrix s[maxn << 2] , tag[maxn << 2] ;
void build(int l , int r , int o) {
tag[o].clr() ;
if(l == r) {
s[o] = qpow(qwq , a[l]) ;
return ;
}
int mid = l + r >> 1 ;
build(l , mid , o << 1) ;
build(mid + 1 , r , o << 1 | 1) ;
s[o] = s[o << 1] + s[o << 1 | 1] ;
}
void psd(int o) {
if(tag[o].empty()) return ;
tag[o << 1] = tag[o << 1] * tag[o] ;
tag[o << 1 | 1] = tag[o << 1 | 1] * tag[o] ;
s[o << 1] = s[o << 1] * tag[o] ;
s[o << 1 | 1] = s[o << 1 | 1] * tag[o] ;
tag[o].clr() ;
}
void upd(int a , int b , int l , int r , matrix x , int o) {
if(a <= l && r <= b) {
s[o] = s[o] * x ;
tag[o] = tag[o] * x ;
return ;
}
psd(o) ;
int mid = l + r >> 1 ;
if(a <= mid) upd(a , b , l , mid , x , o << 1) ;
if(b > mid) upd(a , b , mid + 1 , r , x , o << 1 | 1) ;
s[o] = s[o << 1] + s[o << 1 | 1] ;
}
matrix qry(int a , int b , int l , int r , int o) {
if(a <= l && r <= b) {
return s[o] ;
} psd(o) ;
int mid = l + r >> 1 ;
matrix res ;
if(a <= mid) res = res + qry(a , b , l , mid , o << 1) ;
if(b > mid) res = res + qry(a , b , mid + 1 , r , o << 1 | 1) ;
return res ;
}
signed main() {
#ifdef _WIN64
freopen("testdata.in" , "r" , stdin) ;
#endif
qwq.a[1][1] = qwq.a[1][2] = qwq.a[2][1] = 1 ;
qwq.a[2][2] = 0 ;
in >> n >> m ;
rep(i , 1 , n) in >> a[i] ;
build(1 , n , 1) ;
while(m --) {
int opt ;
in >> opt ;
if(opt == 1) {
int l , r , v ;
in >> l >> r >> v ;
upd(l , r , 1 , n , qpow(qwq , v) , 1) ;
}
else {
int l , r ;
in >> l >> r ;
out << qry(l , r , 1 , n , 1).a[1][2] << '\n' ;
}
}
return out.flush(), 0;
}

CF718C Sasha and Array [线段树+矩阵]的更多相关文章

  1. CF718C Sasha and Array 线段树+矩阵加速

    正解:线段树 解题报告: 传送门! 首先这种斐波拉契,又到了1e9的范围,又是求和什么的,自然而然要想到矩阵加速昂 然后这里主要是考虑修改操作,ai+=x如果放到矩阵加速中是什么意思呢QAQ? 那不就 ...

  2. CF718C Sasha and Array 线段树 + 矩阵乘法

    有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$   直接求不好求,改成矩阵乘法的形式:  $a_{i}=M^x\times ...

  3. 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法

    C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...

  4. CF719E. Sasha and Array [线段树维护矩阵]

    CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...

  5. Codeforces Round #373 (Div. 2) E. Sasha and Array 线段树维护矩阵

    E. Sasha and Array 题目连接: http://codeforces.com/contest/719/problem/E Description Sasha has an array ...

  6. codeforces 719E E. Sasha and Array(线段树)

    题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...

  7. Codeforces 719 E. Sasha and Array (线段树+矩阵运算)

    题目链接:http://codeforces.com/contest/719/problem/E 题意:操作1将[l, r] + x; 操作2求f[l] + ... + f[r]; 题解:注意矩阵可以 ...

  8. 【题解】[CF718C Sasha and Array]

    [题解]CF718C Sasha and Array 对于我这种喜欢写结构体封装起来的选手这道题真是太对胃了\(hhh\) 一句话题解:直接开一颗线段树的矩阵然后暴力维护还要卡卡常数 我们来把\(2 ...

  9. Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)

    题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...

随机推荐

  1. 用pyinstaller打包时的图标问题

    前言 因为昨天重新研究了下python的打包方法,今天一番准备把之前写的一个pdf合并软件重新整理一下,打包出来. 但在打包的过程中仍然遇到了一些问题,半年前一番做打包的时候也遇到了一些问题,现在来看 ...

  2. Linux访问权限控制及时间同步实践

    1.编写脚本/root/bin/checkip.sh,每5分钟检查一次,如果发现通过ssh登录失败 次数超过10次,自动将此远程IP放入Tcp Wrapper的黑名单中予以禁止防问 方式一:脚本+定时 ...

  3. 各类JWT库(java)的使用与评价

    [搬运工] 出处:http://andaily.com/blog/?p=956 在 https://jwt.io/ 网站中收录有各类语言的JWT库实现(有关JWT详细介绍请访问 https://jwt ...

  4. 内网客户 通过 公网域名/ip 访问内网web服务器 出错

    在一内部局域网中, client  内网地址为 10.0.0.2     web  服务器内网地址为 10.0.0.1    外网地址为  211.6.15.1    域名为  xx.love.com ...

  5. 高并发之——不得不说的线程池与ThreadPoolExecutor类浅析

    一.抛砖引玉 既然Java中支持以多线程的方式来执行相应的任务,但为什么在JDK1.5中又提供了线程池技术呢?这个问题大家自行脑补,多动脑,肯定没坏处,哈哈哈... 说起Java中的线程池技术,在很多 ...

  6. 基于 HTML5 和 Canvas 实现的 3D 垃圾分类系统

    前言 垃圾分类,一般是指按一定规定或标准将垃圾分类储存.分类投放和分类搬运,从而转变成公共资源的一系列活动的总称.分类的目的是提高垃圾的资源价值和经济价值,力争物尽其用.垃圾在分类储存阶段属于公众的私 ...

  7. Linux运维---1.Ceph分布式存储架构及工作原理

    Ceph理论 Ceph 简介 Ceph 是一个开源项目,它提供软件定义的.统一的存储解决方案 .Ceph 是一个具有高性能.高度可伸缩性.可大规模扩展并且无单点故障的分布式存储系统 . Ceph 是软 ...

  8. webapi+Quartz.NET解决若干定时程序同时运行的问题

    项目现状: 有若干定时程序需要自启动运行,为了简便程序部署等问题,采取这种办法把定时程序集中管理到webapi中跟随api发布 代码架构介绍: 新建一个类库,类库引用Quartz(Quartz.2.3 ...

  9. 手动发布本地jar包到Nexus私服

    1.Nexus配置 1. 在Nexus私服上建立仓库,用于盛放jar包,如名叫3rd_part. 2. 注册用户Nuxus用户,如名叫dev,密码dev_123. 3. 给dev用户分配能访问3rd_ ...

  10. 简单的说说tippyjs的使用

    我们会接触到很多插件的使用,但是我们该如何的去使用呢,本人建议多学习英语,会对开发很有帮助的 为什么说是多去学习它,接下来我们就来说说: 当你没学习英语看到下面的官网是这样子的 当你会英语了,你就会觉 ...