题意:

维护一个序列,支持两种操作:
1.区间[l,r]的权值+x
2.询问区间[l,r]的函数和,即∑fib(x)这里的函数即斐波那契函数
数据范围:1≤n,q≤105

思路:
一般求斐波那契函数的方法可以考虑矩阵乘法,这里也是这样的。
我们不用线段树维护权值,我们用线段树维护线段树维护区间矩阵和。
有一个矩阵乘法的性质:A*B+A*C=A*(B+C)
在求斐波那契数列中,是A*F,A是变换矩阵,F是列矩阵
那么我们用线段树的lazy标记维护A矩阵,然后用sum维护F矩阵
之后在线段树上,就变成了区间更新乘以x。

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
const int mod=,N=;
int n,m,op,xx,yy,zz;
struct Matrix{
int a[][];
void init(){memset(a,,sizeof(a));}
void dia(){a[][]=a[][]=,a[][]=a[][]=;}
}sum[N<<],lazy[N<<],base;
Matrix operator*(Matrix a,Matrix b){
Matrix c;c.init();
for(int i=;i<;i++)
for(int j=;j<;j++)
for(int k=;k<;k++)
c.a[i][j]=(1ll*a.a[i][k]*b.a[k][j]+c.a[i][j])%mod;
return c;
}
Matrix operator+(Matrix a,Matrix b){
Matrix c;c.init();
for(int i=;i<;i++)
for(int j=;j<;j++)
c.a[i][j]=(a.a[i][j]+b.a[i][j])%mod;
return c;
}
Matrix operator^(Matrix a,int b){
Matrix c;c.dia();
while(b){
if(b&)c=c*a;
a=a*a,b>>=;
}return c;
}
void push_up(int pos){sum[pos]=sum[pos<<]+sum[pos<<|];}
void build(int l,int r,int pos){
if(l==r){scanf("%d",&xx);sum[pos]=base^(xx-);return;}
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
build(l,mid,lson),build(mid+,r,rson);
lazy[pos].dia(),push_up(pos);
}
void push_down(int pos,int lson,int rson){
lazy[lson]=lazy[lson]*lazy[pos],sum[lson]=sum[lson]*lazy[pos];
lazy[rson]=lazy[rson]*lazy[pos],sum[rson]=sum[rson]*lazy[pos];
lazy[pos].dia();
}
Matrix query(int l,int r,int pos,int L,int R){
if(l>=L&&r<=R)return sum[pos];
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
push_down(pos,lson,rson);
if(mid<L)return query(mid+,r,rson,L,R);
else if(mid>=R)return query(l,mid,lson,L,R);
else return query(l,mid,lson,L,R)+query(mid+,r,rson,L,R);
}
void insert(int l,int r,int pos,int L,int R,Matrix wei){
if(l>=L&&r<=R){sum[pos]=sum[pos]*wei;lazy[pos]=lazy[pos]*wei;return;}
int mid=(l+r)>>,lson=pos<<,rson=pos<<|;
push_down(pos,lson,rson);
if(mid<L)insert(mid+,r,rson,L,R,wei);
else if(mid>=R)insert(l,mid,lson,L,R,wei);
else insert(l,mid,lson,L,R,wei),insert(mid+,r,rson,L,R,wei);
push_up(pos);
}
int main(){
base.a[][]=base.a[][]=base.a[][]=;
scanf("%d%d",&n,&m),build(,n,);
while(m--){
scanf("%d%d%d",&op,&xx,&yy);
if(op==)scanf("%d",&zz),insert(,n,,xx,yy,base^zz);
else printf("%d\n",query(,n,,xx,yy).a[][]);
}
}

Codeforces 718C 线段树+矩乘的更多相关文章

  1. Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论

    Bash and a Tough Math Puzzle CodeForces 914D 线段树+gcd数论 题意 给你一段数,然后小明去猜某一区间内的gcd,这里不一定是准确值,如果在这个区间内改变 ...

  2. Codeforces Round #424 (Div. 2, rated, based on VK Cup Finals) Problem E (Codeforces 831E) - 线段树 - 树状数组

    Vasily has a deck of cards consisting of n cards. There is an integer on each of the cards, this int ...

  3. BZOJ 4085 丧心病狂的毒瘤题目 线段树+矩乘

    思路: 一眼矩阵快速幂 再用线段树维护一下矩阵就完了... 我hhhhh    哎我还是too young,too simple 入了这个大坑 线段树维护9个值 以上 如果A+1   转移矩阵是这个样 ...

  4. Codeforces 938G 线段树分治 线性基 可撤销并查集

    Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...

  5. codeforces 1136E 线段树

    codeforces 1136E: 题意:给你一个长度为n的序列a和长度为n-1的序列k,序列a在任何时候都满足如下性质,a[i+1]>=ai+ki,如果更新后a[i+1]<ai+ki了, ...

  6. Z - New Year Tree CodeForces - 620E 线段树 区间种类 bitset

    Z - New Year Tree CodeForces - 620E 这个题目还没有写,先想想思路,我觉得这个题目应该可以用bitset, 首先这个肯定是用dfs序把这个树转化成线段树,也就是二叉树 ...

  7. D - The Bakery CodeForces - 834D 线段树优化dp···

    D - The Bakery CodeForces - 834D 这个题目好难啊,我理解了好久,都没有怎么理解好, 这种线段树优化dp,感觉还是很难的. 直接说思路吧,说不清楚就看代码吧. 这个题目转 ...

  8. B - Legacy CodeForces - 787D 线段树优化建图+dij最短路 基本套路

    B - Legacy CodeForces - 787D 这个题目开始看过去还是很简单的,就是一个最短路,但是这个最短路的建图没有那么简单,因为直接的普通建图边太多了,肯定会超时的,所以要用线段树来优 ...

  9. CodeForces 343D 线段树维护dfs序

    给定一棵树,初始时树为空 操作1,往某个结点注水,那么该结点的子树都注满了水 操作2,将某个结点的水放空,那么该结点的父亲的水也就放空了 操作3,询问某个点是否有水 我们将树进行dfs, 生成in[u ...

随机推荐

  1. LINUX应用开发工程师职位(含答案)

    就业模拟测试题-LINUX应用开发工程师职位 本试卷从考试酷examcoo网站导出,文件格式为mht,请用WORD/WPS打开,并另存为doc/docx格式后再使用 试卷编号:143989试卷录入者: ...

  2. .NET-高并发及限流方案

    前言:高并发对我们来说应该都不陌生,特别想淘宝秒杀,竞价等等,使用的非常多,如何在高并发的情况下,使用限流,保证业务的进行呢.以下是一个实例,不喜勿喷! 总体思路: 1.  用一个环形来代表通过的请求 ...

  3. js中匿名函数的N种写法

    匿名函数没有实际名字,也没有指针,怎么执行? 关于匿名函数写法,很发散~ +号是让函数声明转换为函数表达式.汇总一下 最常见的用法: 代码如下: (function() {  alert('water ...

  4. 页面中插入视频的方法---video/embed/iframe总结

    1. video标签 当前主流的方法当然是HTML5中的video标签了,但是 当前,video 元素只支持三种视频格式: Ogg = 带有 Theora 视频编码和 Vorbis 音频编码的 Ogg ...

  5. Codeforces Round #226 (Div. 2) C题

    数论好题 题目要求:求给定序列的素因子如果在给定区间内该数字个数加1; 思路:打表时求出包含给素数因子的数的个数,详见代码 1 #include<cstring> +;      scan ...

  6. Linux/windows查看设置环境变量指令

    一.Linux: 1.查看所有环境变量的指令 方法1:$:export (export命令作用是显示.设置或删除linux环境变量:) 方法2:$:env 2.查看某个指定的环境变量 方法1:$:ex ...

  7. UIColor用自定义颜色,TableView去掉背景色

    1.用mac系统自带的数码测色计,选RGB模式,将值添加到ColorWithRed:xxx.0/255 最后的alpha选1.0 2.TableView的背景色要用setBackgroundView的 ...

  8. Ubuntu 16.04安装Bless十六进制编辑器

    一款专注于十六进制的编辑器. 安装: sudo apt-get install bless 启动:

  9. MySQL Workbench查看和修改表字段的Comment值

    查看: 选择单个表->[右键]->[Table Inspector] 再选择Columns选项卡即可,把表格拉倒最后一列. 编辑: 选择单个表->[右键]->[Alter Ta ...

  10. 【转】MySQL随机字符串生成

    DROP FUNCTION IF EXISTS rand_string; DELIMITER $$ CREATE FUNCTION rand_string(str_length TINYINT UNS ...