题意:

维护一个序列,支持两种操作:
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. sublime 使用笔记

    unbuntu安装sublime---------------------------------------------sudo add-apt-repository ppa:webupd8team ...

  2. Reading Lists

    * Non-academic 1. Slowing Down to the Speed of Life, by Richard Carlson and Joseph Bailey.2. Your Mo ...

  3. circumferential averge streamwise velocity using Tecplot and Matlab

    Input: results from solver output: circumferential averge physical quantities( such as streamwise ve ...

  4. Spring核心技术(二)——Spring的依赖及其注入

    本文将继续前文,描述Spring IoC中的依赖处理. 依赖 一般情况下企业应用不会只有一个对象(或者是Spring Bean).甚至最简单的应用都要多个对象来协同工作来让终端用户看到一个完整的应用的 ...

  5. Stones HDU 1896

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1896 题目大意: 有n个石头,每个石头有:p  它所在的位置 ,d  它能扔多远 从0 开始,遇到第奇 ...

  6. Android第三方开源SwitchButton

    Android第三方开源SwitchButton Android SwitchButton是github上的一个第三方开源项目,其项目主页是:https://github.com/kyleduo/Sw ...

  7. mariadb-10GTID复制及多源复制

    ---本文大纲 一.什么是GTID 二.应用场景 三.多线程复制说明 四.实现过程 五.多源复制原理 六.实现过程 ---------------------------------- 一.什么是GI ...

  8. Hihocoder 1337 (splay)

    Problem 平衡树 SBT 题目大意 维护一个序列,支持两种操作. 操作一:插入一个数. 操作二:询问第k小的数. 解题分析 ~~刷刷水题,再熟悉一下splay的基本操作. ps:哇咔咔,有连续四 ...

  9. Oops, 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine error

    环境: Win7 64位 + VS2005 + Office2013 64位 现象:程序为一个Excel导入程序,导入时报「'Microsoft.ACE.OLEDB.12.0' provider is ...

  10. CN Internet

    来自为知笔记(Wiz)