Sasha and Array
5 seconds
256 megabytes
standard input
standard output
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 modulo109 + 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.
5 4
1 1 2 1 1
2 1 5
1 2 4 2
2 2 4
2 1 5
5
7
9
Initially, array a is equal to 1, 1, 2, 1, 1.
The answer for the first query of the second type is f(1) + f(1) + f(2) + f(1) + f(1) = 1 + 1 + 1 + 1 + 1 = 5.
After the query 1 2 4 2 array a is equal to 1, 3, 4, 3, 1.
The answer for the second query of the second type is f(3) + f(4) + f(3) = 2 + 3 + 2 = 7.
The answer for the third query of the second type is f(1) + f(3) + f(4) + f(3) + f(1) = 1 + 2 + 3 + 2 + 1 = 9.
分析:线段树维护矩阵;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define rep(i,m,n) for(i=m;i<=n;i++)
#define rsp(it,s) for(set<int>::iterator it=s.begin();it!=s.end();it++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define Lson L, mid, rt<<1
#define Rson mid+1, R, rt<<1|1
const int maxn=1e5+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qpow(ll p,ll q){ll f=;while(q){if(q&)f=f*p%mod;p=p*p%mod;q>>=;}return f;}
int n,m,k,t,a[maxn];
struct Matrix
{
int a[][];
Matrix()
{
memset(a,,sizeof(a));
}
void init()
{
for(int i=;i<;i++)
for(int j=;j<;j++)
a[i][j]=(i==j);
}
Matrix operator + (const Matrix &B)const
{
Matrix C;
for(int i=;i<;i++)
for(int j=;j<;j++)
C.a[i][j]=(a[i][j]+B.a[i][j])%mod;
return C;
}
Matrix operator * (const Matrix &B)const
{
Matrix C;
for(int i=;i<;i++)
for(int k=;k<;k++)
for(int j=;j<;j++)
C.a[i][j]=(C.a[i][j]+1LL*a[i][k]*B.a[k][j])%mod;
return C;
}
Matrix operator ^ (const int &t)const
{
Matrix A=(*this),res;
res.init();
int p=t;
while(p)
{
if(p&)res=res*A;
A=A*A;
p>>=;
}
return res;
}
};
Matrix f;
struct Node
{
Matrix sum,lazy;
} T[maxn<<]; void PushUp(int rt)
{
T[rt].sum = T[rt<<].sum + T[rt<<|].sum;
} void PushDown(int L, int R, int rt)
{
int mid = (L + R) >> ;
Matrix t = T[rt].lazy;
T[rt<<].sum = t * T[rt<<].sum;
T[rt<<|].sum = t * T[rt<<|].sum;
T[rt<<].lazy = t * T[rt<<].lazy;
T[rt<<|].lazy = t *T[rt<<|].lazy;
T[rt].lazy.init();
} void Build(int L, int R, int rt)
{
T[rt].lazy.init();
if(L == R)
{
T[rt].sum=f^(a[L]-);
return ;
}
int mid = (L + R) >> ;
Build(Lson);
Build(Rson);
PushUp(rt);
} void Update(int l, int r, Matrix v, int L, int R, int rt)
{
if(l==L && r==R)
{
T[rt].lazy = v * T[rt].lazy;
T[rt].sum = v * T[rt].sum;
return ;
}
int mid = (L + R) >> ;
if(T[rt].lazy.a[][]||T[rt].lazy.a[][])PushDown(L, R, rt);
if(r <= mid) Update(l, r, v, Lson);
else if(l > mid) Update(l, r, v, Rson);
else
{
Update(l, mid, v, Lson);
Update(mid+, r, v, Rson);
}
PushUp(rt);
} ll Query(int l, int r, int L, int R, int rt)
{
if(l==L && r== R)
{
return T[rt].sum.a[][];
}
int mid = (L + R) >> ;
if(T[rt].lazy.a[][]||T[rt].lazy.a[][]) PushDown(L, R, rt);
if(r <= mid) return Query(l, r, Lson);
else if(l > mid) return Query(l, r, Rson);
return (Query(l, mid, Lson) + Query(mid + , r, Rson))%mod;
}
struct node
{
int a,x,y,z;
}op[maxn];
void init()
{
f.a[][]=,f.a[][]=;
f.a[][]=,f.a[][]=;
}
int main()
{
int i,j;
init();
scanf("%d%d",&n,&m);
rep(i,,n)scanf("%d",&a[i]);
Build(,n,);
rep(i,,m)
{
scanf("%d",&op[i].a);
if(op[i].a==)
{
scanf("%d%d%d",&op[i].x,&op[i].y,&op[i].z);
Update(op[i].x,op[i].y,f^op[i].z,,n,);
}
else
{
scanf("%d%d",&op[i].x,&op[i].y);
printf("%lld\n",Query(op[i].x,op[i].y,,n,));
}
}
//system("Pause");
return ;
}
Sasha and Array的更多相关文章
- 【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 ...
- 【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 ...
- Codeforces Round #373 (Div. 2) E. Sasha and Array 矩阵快速幂+线段树
E. Sasha and Array time limit per test 5 seconds memory limit per test 256 megabytes input standard ...
- 【题解】[CF718C Sasha and Array]
[题解]CF718C Sasha and Array 对于我这种喜欢写结构体封装起来的选手这道题真是太对胃了\(hhh\) 一句话题解:直接开一颗线段树的矩阵然后暴力维护还要卡卡常数 我们来把\(2 ...
- E. Sasha and Array 矩阵快速幂 + 线段树
E. Sasha and Array 这个题目没有特别难,需要自己仔细想想,一开始我想了一个方法,不对,而且还很复杂,然后lj提示了我一下说矩阵乘,然后再仔细想想就知道怎么写了. 这个就是直接把矩阵放 ...
- 718C Sasha and Array
传送门 题目 Sasha has an array of integers a1, a2, ..., an. You have to perform m queries. There might be ...
随机推荐
- python2.7学习记录
一.两个学习网址(2.7已经过时,建议直接学习3) http://blog.csdn.net/longxibendi/article/details/41949215 http://www.liaox ...
- 如何禁用电脑USB接口
方法一,BIOS设置法 重新启动计算机,在开机过程中,点击键盘上的“Delete”键,进入BIOS设置界面,选择“Integrated Peripherals”选项,展开后将“USB 1.1 Cont ...
- STM32F446 OTG_FS_DP/DM调试
之前项目用STM32F207,现在升级到用STM32F446处理器,用到USB的OTG_FS模式接法: 1.USB只连接了DP/DM 2.DP需上拉1.5K的电阻到3.3V 3.PA9(VBUS) 和 ...
- MySQL 的实时性能监控利器【转】
操作系统及MySQL数据库的实时性能状态数据尤为重要,特别是在有性能抖动的时候,这些实时的性能数据可以快速帮助你定位系统或MySQL数据库的性能瓶颈,就像你在Linux系统上使用「top,sar,io ...
- Linux中切换用户变成-bash4.1-$的解决方法【转】
转自 Linux中切换用户变成-bash4.1-$的解决方法 - xia_xia的博客 - 博客频道 - CSDN.NEThttp://blog.csdn.net/xia_xia0919/articl ...
- 矩阵类c++实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 3 ...
- Entity Framework 学习中级篇3—存储过程(中)
目前,EF对存储过程的支持并不完善.存在以下问题: l EF不支持存储过程返回多表联合查询的结果集. l EF仅支持返回返回某个表的全部字段,以便转换成对应的实体.无法 ...
- Linux查询系统配置常用命令
系统 # uname -a # 查看内核/操作系统/CPU信息# head -n 1 /etc/issue # 查看操作系统版本# cat /proc/cpuinfo ...
- 把perl脚本编译成exe
来源:http://www.veryhuo.com/a/view/38338.html 今天想把 perl 脚本编译成 exe 以便脱离 perl 解释器独立运行.都可以生成PERL的PE文件,在PE ...
- shell中 if else以及大于、小于、等于逻辑表达式介绍
比如比较字符串.判断文件是否存在及是否可读等,通常用"[]"来表示条件测试. 注意:这里的空格很重要.要确保方括号的空格.笔者就曾因为空格缺少或位置不对,而浪费好多宝贵的时间. i ...