CF718C Sasha and Array [线段树+矩阵]
我们考虑线性代数上面的矩阵知识
啊呸,是基础数学
斐波那契的矩阵就不讲了
定义矩阵 \(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 [线段树+矩阵]的更多相关文章
- CF718C Sasha and Array 线段树+矩阵加速
正解:线段树 解题报告: 传送门! 首先这种斐波拉契,又到了1e9的范围,又是求和什么的,自然而然要想到矩阵加速昂 然后这里主要是考虑修改操作,ai+=x如果放到矩阵加速中是什么意思呢QAQ? 那不就 ...
- CF718C Sasha and Array 线段树 + 矩阵乘法
有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$ 直接求不好求,改成矩阵乘法的形式: $a_{i}=M^x\times ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- CF719E. Sasha and Array [线段树维护矩阵]
CF719E. Sasha and Array 题意: 对长度为 n 的数列进行 m 次操作, 操作为: a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9 求 F[a[l]]+ ...
- 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 ...
- codeforces 719E E. Sasha and Array(线段树)
题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...
- Codeforces 719 E. Sasha and Array (线段树+矩阵运算)
题目链接:http://codeforces.com/contest/719/problem/E 题意:操作1将[l, r] + x; 操作2求f[l] + ... + f[r]; 题解:注意矩阵可以 ...
- 【题解】[CF718C Sasha and Array]
[题解]CF718C Sasha and Array 对于我这种喜欢写结构体封装起来的选手这道题真是太对胃了\(hhh\) 一句话题解:直接开一颗线段树的矩阵然后暴力维护还要卡卡常数 我们来把\(2 ...
- Wannafly Winter Camp 2019.Day 8 div1 E.Souls-like Game(线段树 矩阵快速幂)
题目链接 \(998244353\)写成\(99824435\)然后调这个线段树模板1.5h= = 以后要注意常量啊啊啊 \(Description\) 每个位置有一个\(3\times3\)的矩阵, ...
随机推荐
- Windows搭建IIS服务器使用NATAPP实现内网穿透
目的:外网可以访问本地网页. 步骤: 一.实现内网访问 1.Win+Q搜索[控制面板],选择[程序],点击[启用或关闭Windows功能], 2.勾选[Internet Information Ser ...
- 《古剑奇谭3》千秋戏辅助工具(前端React制作)
前言 一直身在武汉,基于众所周知的疫情原因,这个春节只能宅着. 不过其实这个春节是这些年来过得最爽的一个了. 没有鞭炮,不用四处跑,安安心心呆在家里玩玩游戏看看书写写代码,其实日子过得还是挺悠闲的. ...
- 2020牛客寒假算法基础集训营4 E:最小表达式
E:最小表达式 考察点 : 贪心,高精度 坑点 : 高精度一定不要写错,一定一定不要写错 剩下的就是细节问题 侃侃 : 1.字符串长度达到 5e5,如果要涉及到加法,乘法,普通的肯定会爆 long l ...
- 基于 H5和 3D WebVR 的可视化虚拟现实培训系统
前言 2019 年 VR, AR, XR, 5G, 工业互联网等名词频繁出现在我们的视野中,信息的分享与虚实的结合已经成为大势所趋,5G 是新一代信息通信技术升级的重要方向,工业互联网是制造业转型升级 ...
- 《自拍教程16》cmd的常用技巧
cmd.exe是Windows 自带的命令行操作交互界面软件. 虽然功能有限,但是毕竟是默认的命令行操作交互界面软件. 肯定所有的电脑都是自带的. 当然现在已经有很多改良版的,交互体验更好的cmd类似 ...
- 获取出口IP地址
curl https://www.ipaddress.com/ |grep "My IPv4 Address" # 推荐 curl icanhazip.com curl www.t ...
- 杭电-------2052Picture(C语言)
#include<stdio.h> int main() { int width, height; int i, j; while (~scanf("%d %d", & ...
- 【全集】大数据Linux基础
课程介绍 本课程是由猎豹移动大数据架构师,根据公司大数据平台的运维情况,精心设计和打磨的大数据必备Linux课程.通过本课程的学习大数据新手能够少走弯路,快速掌握Linux常用命令及Shell编程,为 ...
- 【HDU - 2859 】Phalanx (dp 最大对称子图)
Phalanx 先搬翻译 Descriptions: 给你一个矩阵,只由小写或大写字母构成.求出它的最大对称子矩阵的边长. 其中对称矩阵是一个k*k的矩阵,它的元素关于从左下角到右上角的对角线对称.例 ...
- Java高级项目实战02:客户关系管理系统CRM系统模块分析与介绍
本文承接上一篇:Java高级项目实战之CRM系统01:CRM系统概念和分类.企业项目开发流程 先来CRM系统结构图: 每个模块作用介绍如下: 1.营销管理 营销机会管理:针对企业中客户的质询需求所建立 ...