718C Sasha and Array
题目
Sasha has an array of integers a1, a2, ..., an. You have to perform m queries. There might be queries of two types:
- 1 l r x — increase all integers on the segment from l to r by values x;
- 2 l r — find
, where f(x) is the x-th Fibonacci number. As this number may be large, you only have to find it modulo 109 + 7.
In this problem we define Fibonacci numbers as follows: f(1) = 1, f(2) = 1, f(x) = f(x - 1) + f(x - 2) for all x > 2.
Sasha is a very talented boy and he managed to perform all queries in five seconds. Will you be able to write the program that performs as well as Sasha?
The first line of the input contains two integers n and m (1 ≤ n ≤ 100 000, 1 ≤ m ≤ 100 000) — the number of elements in the array and the number of queries respectively.
The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109).
Then follow m lines with queries descriptions. Each of them contains integers tpi, li, ri and may be xi (1 ≤ tpi ≤ 2, 1 ≤ li ≤ ri ≤ n, 1 ≤ xi ≤ 109). Here tpi = 1 corresponds to the queries of the first type and tpi corresponds to the queries of the second type.
It's guaranteed that the input will contains at least one query of the second type.
For each query of the second type print the answer modulo 109 + 7.
题目大意
给你一个长度为n的数列an,有两种操作
1、将L到R的ai加上X
2、询问L到R之间,f(aL)+f(aL+1)+……+f(aR)的和
f是斐波那契函数
分析
我们可以将斐波那契数转化成它所对应的矩阵,对于每一次加x就是给原来矩阵乘上斐波那契矩阵的x次方。将为赋值的矩阵全部初始化为单位矩阵,然后进行朴素的线段树为何两节点之和即可。
代码
#pragma G++ optimize (2)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define rri register int
const int mod=1e9+;
struct mat {
int g[][];
};
mat d[],one,per;
mat add[];
inline mat operator * (const mat a,const mat b){
mat c;
c.g[][]=c.g[][]=c.g[][]=c.g[][]=;
for(rri i=;i<=;++i)
for(rri k=;k<=;++k)
for(rri j=;j<=;++j)
c.g[i][j]=(c.g[i][j]+(long long)a.g[i][k]*b.g[k][j]%mod)%mod;
return c;
}
inline mat operator + (const mat a,const mat b){
mat c;
for(rri i=;i<=;++i)
for(rri j=;j<=;++j)
c.g[i][j]=(a.g[i][j]+b.g[i][j])%mod;
return c;
}
inline mat pw(mat a,int p){
mat res=a;
p-=;
while(p){
if(p&)res=res*a;
a=a*a;
p>>=;
}
return res;
}
inline int read(){
int x=,f=;char s=getchar();
while(s<''||s>''){if(s=='-')f=-;s=getchar();}
while(s>=''&&s<=''){x=(x<<)+(x<<)+(s-'');s=getchar();}
return f*x;
}
inline void build(int le,int ri,int pl,mat k,int wh){
add[wh]=per;
if(le==ri){
d[wh]=k;
return;
}
int mid=(le+ri)>>;
if(mid>=pl)build(le,mid,pl,k,wh<<);
else build(mid+,ri,pl,k,wh<<|);
d[wh]=d[wh<<]+d[wh<<|];
}
inline void pd(int wh){
if(add[wh].g[][]!=||add[wh].g[][]!=||
add[wh].g[][]!=||add[wh].g[][]!=){
add[wh<<]=add[wh<<]*add[wh];
add[wh<<|]=add[wh<<|]*add[wh];
d[wh<<]=d[wh<<]*add[wh];
d[wh<<|]=d[wh<<|]*add[wh];
add[wh]=per;
}
}
inline void update(int le,int ri,int x,int y,mat k,int wh){
if(le>=x&&ri<=y){
add[wh]=add[wh]*k;
d[wh]=d[wh]*k;
return;
}
int mid=(le+ri)>>;
pd(wh);
if(mid>=x)update(le,mid,x,y,k,wh<<);
if(mid<y)update(mid+,ri,x,y,k,wh<<|);
d[wh]=d[wh<<]+d[wh<<|];
}
inline int q(int le,int ri,int x,int y,int wh){
if(le>=x&&ri<=y)return d[wh].g[][]%mod;
int mid=(le+ri)>>,ans=;
pd(wh);
if(mid>=x)ans=(ans+q(le,mid,x,y,wh<<))%mod;
if(mid<y)ans=(ans+q(mid+,ri,x,y,wh<<|))%mod;
d[wh]=d[wh<<]+d[wh<<|];
return ans%mod;
}
int main()
{ int n,m,x,l,r,k;
one.g[][]=,one.g[][]=one.g[][]=one.g[][]=;
per.g[][]=per.g[][]=,per.g[][]=per.g[][]=;
n=read(),m=read();
for(rri i=;i<=n;++i){
x=read();
build(,n,i,pw(one,x),);
}
for(rri i=;i<=m;++i){
k=read();
if(k==){
l=read(),r=read(),x=read();
update(,n,l,r,pw(one,x),);
}else {
l=read(),r=read();
printf("%d\n",q(,n,l,r,)%mod);
}
}
return ;
}
718C Sasha and Array的更多相关文章
- CodeForces 718C Sasha and Array
线段树. 线段树维护区间矩阵和,操作都是最简单的线段树.$lazy$标记不要记录乘了几次,直接记录乘了几次之后的矩阵就可以了,不然每次下传的时候再算一遍时间复杂度会提高. #pragma commen ...
- Codeforces 718C. Sasha and Array(线段树)
传送门 解题思路: 这道题给了我们一个崭新的角度来看线段树. 我们常常使用的线段树是维护区间的函数的. 这里呢,提示我们线段树其实还可以维护递推. 美好的矩阵递推性质支持了这一功能. 或者说,对于递推 ...
- [CF 718C] Sasha and Array
传送门 Solution 用线段树维护矩阵 第一个操作相当于区间乘 第二个操作相当于区间求和 Code #include<bits/stdc++.h> #define ll long l ...
- 【Codeforces718C】Sasha and Array 线段树 + 矩阵乘法
C. Sasha and Array time limit per test:5 seconds memory limit per test:256 megabytes input:standard ...
- codeforces 719E E. Sasha and Array(线段树)
题目链接: E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input sta ...
- Sasha and Array
Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input standard inp ...
- 【codeforces 718 C&D】C. Sasha and Array&D. Andrew and Chemistry
C. Sasha and Array 题目大意&题目链接: http://codeforces.com/problemset/problem/718/C 长度为n的正整数数列,有m次操作,$o ...
- 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 ...
随机推荐
- python 计数器类Counter的用法
简单操作: import collections A=['a','b','b','c','d','b','a'] count=collections.Counter(A) print(count) C ...
- MySQL引擎各个引擎对比介绍
1.什么是存储引擎? 存储引擎类似于录制的视频文件,可以转换成不同的格式,如MP4,avi等格式,而存储在我们的磁盘上也会存在于不同类型的文件系统中如:Windows里常见的NTFS,fat32等.存 ...
- linux 缺少libxxx.a 静态链接库
首先去官方网站下载gdb的源码包,我下载的7.4.1版本的源码包,解压开来,进入到源码包的根目录下.对于一个源码包,拿到手里首先要阅读的就是README,然后看一下INSTALL文件,这个文件里编译源 ...
- bzoj4513 储能表
求 $\sum\limits_{i=0}^{n-1} \sum\limits_{j=0}^{m-1} max((x \space xor \space j) - k,0)$ ,膜 $p$ $n,m \ ...
- maven module开发 自动打包
http://blog.csdn.net/u011113713/article/details/52413903 http://blog.csdn.net/sisyphus_z/article/det ...
- js 自定义方法 设置可选参数的方法
原链接 http://www.cnblogs.com/RightDear/p/3156652.html PHP有个很方便的用法是在定义函数时可以直接给参数设默认值,如: function simue ...
- oracle如何insert into 多个values
稍微熟悉Oracle的都知道,如果我们想一条SQL语句向表中插入多个值的话,如果如下语句 INSERT INTO 某表 VALUES(各个值),VALUES(各个值),.....; 这样会报错的,因为 ...
- 开启MySQL的sql语句记录
在开发的时候经常会想看一下MySQL最终执行的sql或者想保存sql记录,所以我们可以启用MySQL的sql记录功能. 开启方法:Linux下编辑MySQL的my.cnf文件,windows下编辑my ...
- mysql之 MySQL 主从基于position复制原理概述
1 .主从复制简介MySQL 主从复制就是将一个 MySQL 实例(Master)中的数据实时复制到另一个 MySQL 实例(slave)中,而且这个复制是一个异步复制的过程.实现整个复制操作主要由三 ...
- FPGA的年龄
FPGA的年龄 1984年,Xilinx公司发布了第一个FPGA(但直到1985年这些器件才真正发货).尽管这些器件比当时那些简单的可编程逻辑器件(PLD)复杂的多,但大多数数字设计工程师却仅仅用这些 ...