CF719E. Sasha and Array

题意:

对长度为 n 的数列进行 m 次操作, 操作为:

  1. a[l..r] 每一项都加一个常数 C, 其中 0 ≤ C ≤ 10^9
  2. 求 F[a[l]]+F[a[l+1]]+...F[a[r]] mod 1e9+7 的余数

矩阵快速幂求斐波那契

矩阵满足乘法分配律和结合律!

所以可以每个节点维护矩阵/矩阵和,区间加相当于区间乘矩阵

注意:不要把快速幂写在里面,复杂度平添一个log。把\(B^C\)算出来之后传进去就好了

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
#define lc x<<1
#define rc x<<1|1
#define mid ((l+r)>>1)
#define lson lc, l, mid
#define rson rc, mid+1, r
const int N = 1e5+5, P = 1e9+7; int n, m;
struct Matrix {
ll a[2][2];
ll* operator [](int x) {return a[x];}
Matrix(int p=0) {
if(!p) a[0][0] = a[0][1] = a[1][0] = a[1][1] = 0;
else a[0][0] = a[1][1] = 1, a[0][1] = a[1][0] = 0;
}
} B; Matrix operator + (Matrix a, Matrix b) {
Matrix c;
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
c[i][j] = (a[i][j] + b[i][j]) %P;
return c;
} Matrix operator * (Matrix a, Matrix b) {
Matrix c;
for(int i=0; i<2; i++)
for(int j=0; j<2; j++) {
ll &x = c[i][j];
for(int k=0; k<2; k++)
x = (x + a[i][k] * b[k][j] %P) %P;
}
return c;
} Matrix operator ^ (Matrix a, int b) {
Matrix ans(1);
ans[0][0] = ans[1][1] = 1;
for(; b; b>>=1, a=a*a)
if(b & 1) ans = ans*a;
return ans;
} struct meow {
Matrix f;
Matrix v;
int c;
meow() {f[0][0] = 1; v[0][0] = v[1][1] = 1;}
} t[N<<2]; void paint(int x, int l, int r, int d, Matrix &v) {
t[x].c += d;
t[x].v = v * t[x].v;
t[x].f = v * t[x].f;
}
void push_down(int x, int l, int r) {
if(t[x].c) {
paint(lson, t[x].c, t[x].v);
paint(rson, t[x].c, t[x].v);
t[x].c = 0;
t[x].v = Matrix(1);
}
}
void merge(int x) {
t[x].f = t[lc].f + t[rc].f;
} void build(int x, int l, int r) {
if(l == r) {
cin >> t[x].c;
if(t[x].c > 1) t[x].f = (B ^ (t[x].c - 1)) * t[x].f;
} else {
build(lson);
build(rson);
merge(x);
}
} void Add(int x, int l, int r, int ql, int qr, int d, Matrix &v) {
if(ql <= l && r <= qr) paint(x, l, r, d, v);
else {
push_down(x, l, r);
if(ql <= mid) Add(lson, ql, qr, d, v);
if(mid < qr) Add(rson, ql, qr, d,v );
merge(x);
}
} ll Que(int x, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return t[x].f[0][0];
else {
push_down(x, l, r);
ll ans = 0;
if(ql <= mid) ans = (ans + Que(lson, ql, qr)) %P;
if(mid < qr) ans = (ans + Que(rson, ql, qr)) %P;
return ans;
}
} int main() {
//freopen("in", "r", stdin);
ios::sync_with_stdio(false); cin.tie(); cout.tie(); B[0][0] = B[0][1] = B[1][0] = 1;
cin >> n >> m;
build(1, 1, n); for(int i=1; i<=m; i++) {
int tp, l, r, x;
cin >> tp >> l >> r;
if(tp == 1) {
cin >> x;
Matrix t = B^x;
Add(1, 1, n, l, r, x, t);
} else cout << Que(1, 1, n, l, r) << '\n';
}

CF719E. Sasha and Array [线段树维护矩阵]的更多相关文章

  1. 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 ...

  2. 线段树维护矩阵【CF718C】 Sasha and Array

    Description 有一个长为\(n\)的数列\(a_{1},a_{2}...a_{n}\),你需要对这个数列维护如下两种操作: \(1\space l \space r\space x\) 表示 ...

  3. CF718C Sasha and Array(线段树维护矩阵)

    题解 (不会矩阵加速的先去学矩阵加速) 反正我想不到线段树维护矩阵.我太菜了. 我们在线段树上维护一个区间的斐波那契的列矩阵的和. 然后询问时提取每个符合题意列矩阵的答案项(不是列矩阵存了两项吗,一个 ...

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

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

  5. Subsequence Count 2017ccpc网络赛 1006 dp+线段树维护矩阵

    Problem Description Given a binary string S[1,...,N] (i.e. a sequence of 0's and 1's), and Q queries ...

  6. hdu 5068 线段树维护矩阵乘积

    http://acm.hdu.edu.cn/showproblem.php?pid=5068 题意给的略不清晰 m个询问:从i层去j层的方法数(求连段乘积)或者修改从x层y门和x+1层z门的状态反转( ...

  7. Codeforces 1368H - Breadboard Capacity(最小割+线段树维护矩阵乘法)

    Easy version:Codeforces 题面传送门 & 洛谷题面传送门 Hard version:Codeforces 题面传送门 & 洛谷题面传送门 首先看到这种从某一种颜色 ...

  8. Codeforces 750E - New Year and Old Subsequence(线段树维护矩阵乘法,板子题)

    Codeforces 题目传送门 & 洛谷题目传送门 u1s1 我做这道 *2600 的动力是 wjz 出了道这个套路的题,而我连起码的思路都没有,wtcl/kk 首先考虑怎样对某个固定的串计 ...

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

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

随机推荐

  1. 实验二 Java面向对象程序设计 20175301李锦然实验报告

    实验二 Java面向对象程序设计 实验内容 1. 初步掌握单元测试和TDD 2. 理解并掌握面向对象三要素:封装.继承.多态 3. 初步掌握UML建模 4. 熟悉S.O.L.I.D原则 5. 了解设计 ...

  2. sql server登录名、服务器角色、数据库用户、数据库角色、架构区别联系

    原创链接:https://www.cnblogs.com/lxf1117/p/6762315.html sql server登录名.服务器角色.数据库用户.数据库角色.架构区别联系 1.一个数据库用户 ...

  3. 虚拟机14安装kail Linux

    需要准备虚拟机和kail Linux镜像 1. 2.选择镜像安装,并且添加你的kail Linux镜像文件. 3. 4.在这里需要修改虚拟机名称,也可以不修改就用默认,然后在修改kail Linux的 ...

  4. VIM编辑器使用

  5. 分享一个在线生成微信跳转链接实现微信内跳转浏览器打开URL的工具

    前言 现如今微信对第三方推广链接的审核是越来越严格了,域名在微信中分享转发经常会被拦截,一旦被拦截用户就只能复制链接手动打开浏览器粘贴才能访问,要不然就是换个域名再推,周而复始.无论是哪一种情况都会面 ...

  6. eclipse添加jar包进jar源码debug调试

    1.点击调试配置 2.选中源码 3.点击添加 4.点击java路径变量 5.点击环境变量配置 6.输入名称及jar包复制限定名

  7. Request method 'POST' not supported解决办法

    (1)考虑拦截器是否将该链接拦截

  8. C++变量/函数命名规范

    ## 参照Google C++编程规范之变量命名 1. 变量 变量名一律小写,单词间以下划线相连.类的成员变量以下划线结尾. 普通变量命名 举例: string window_name; // OK ...

  9. python3字符串

    Python3 字符串 Python字符串运算符 + 字符串连接 a + b 输出结果: HelloPython * 重复输出字符串 a*2 输出结果:HelloHello [] 通过索引获取字符串中 ...

  10. ICMP shell

    场景 反向shell的场景下使用 原理 ICMP作为获取反向shell的通道 实践 运行 run.sh报错,可能是因为用的Parrot.改一下就可以了 ifconfig | grep 'inet '| ...