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 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?
Input
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.
Output
For each query of the second type print the answer modulo 109 + 7.
Sample Input
5 4
1 1 2 1 1
2 1 5
1 2 4 2
2 2 4
2 1 5
Sample Output
5
7
9
Hint
题意
给你n个数,两个操作,1是区间增加x,2是查询区间fib(a[i])的和
题解:
回忆一下你怎么做矩阵快速幂fib的,就知道这个更新,其实就是多乘上了一个A^x矩阵。
A = 【0,1;0,0;】这个玩意儿。
然后就可以区间更新呢。
CF官方题解下面有个评论说的很清楚,大家可以看一下。

代码
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
const int maxn = 1e5+5;
struct node
{
long long a[2][2];
void reset()
{
memset(a,0,sizeof(a));
}
void one()
{
reset();
a[0][0]=a[1][1]=1;
}
};
node add(node A,node B)
{
node k;k.reset();
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
k.a[i][j]=(A.a[i][j]+B.a[i][j])%mod;
return k;
}
node mul(node A,node B)
{
node k;memset(k.a,0,sizeof(k.a));
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int t=0;t<2;t++)
k.a[i][j]=(k.a[i][j]+A.a[i][t]*B.a[t][j])%mod;
return k;
}
node qpow(int p)
{
node A;
A.a[0][0]=0,A.a[1][0]=1,A.a[0][1]=1,A.a[1][1]=1;
node K;
K.one();
while(p)
{
if(p%2)K=mul(K,A);
A=mul(A,A);p/=2;
}
return K;
}
typedef node SgTreeDataType;
struct treenode
{
int L , R , flag;
SgTreeDataType sum , lazy;
void update(SgTreeDataType v)
{
sum=mul(sum,v);
lazy=mul(lazy,v);
flag=1;
}
};
treenode tree[maxn*4];
int a[maxn];
inline void push_down(int o)
{
if(tree[o].flag)
{
tree[2*o].update(tree[o].lazy) ; tree[2*o+1].update(tree[o].lazy);
tree[o].flag = 0;tree[o].lazy.one();
}
}
inline void push_up(int o)
{
tree[o].sum = add(tree[o*2].sum,tree[o*2+1].sum);
}
node tmp;
inline void build_tree(int L , int R , int o)
{
tree[o].L = L , tree[o].R = R,tree[o].sum.reset(),tree[o].lazy.one(),tree[o].flag=0;
if(L==R)
{
tree[o].sum=qpow(a[L]);
}
if (R > L)
{
int mid = (L+R) >> 1;
build_tree(L,mid,o*2);
build_tree(mid+1,R,o*2+1);
push_up(o);
}
}
inline void update(int QL,int QR,SgTreeDataType v,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) tree[o].update(v);
else
{
push_down(o);
int mid = (L+R)>>1;
if (QL <= mid) update(QL,QR,v,o*2);
if (QR > mid) update(QL,QR,v,o*2+1);
push_up(o);
}
}
inline SgTreeDataType query(int QL,int QR,int o)
{
int L = tree[o].L , R = tree[o].R;
if (QL <= L && R <= QR) return tree[o].sum;
else
{
push_down(o);
int mid = (L+R)>>1;
SgTreeDataType res;res.reset();
if (QL <= mid) res=add(res,query(QL,QR,2*o));
if (QR > mid) res=add(res,query(QL,QR,2*o+1));
push_up(o);
return res;
}
}
int n,q;
int main()
{
tmp.a[0][0]=0,tmp.a[1][0]=1,tmp.a[0][1]=1,tmp.a[1][1]=1;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
build_tree(1,n,1);
for(int i=1;i<=q;i++)
{
int op;scanf("%d",&op);
if(op==2){
int a,b;scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,1).a[1][0]);
}
else{
int a,b,c;scanf("%d%d%d",&a,&b,&c);
update(a,b,qpow(c),1);
}
}
return 0;
}
Codeforces Round #373 (Div. 2) E. Sasha and 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 ...
- Codeforces Round #271 (Div. 2) E题 Pillars(线段树维护DP)
题目地址:http://codeforces.com/contest/474/problem/E 第一次遇到这样的用线段树来维护DP的题目.ASC中也遇到过,当时也非常自然的想到了线段树维护DP,可是 ...
- 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
题目链接 分析:矩阵快速幂+线段树 斐波那契数列的计算是矩阵快速幂的模板题,这个也没什么很多好解释的,学了矩阵快速幂应该就知道的东西= =这道题比较巧妙的在于需要用线段树来维护矩阵,达到快速查询区间斐 ...
- Codeforces Round #374 (Div. 2) D. Maxim and Array 线段树+贪心
D. Maxim and Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...
- Codeforces Round #312 (Div. 2) E. A Simple Task 线段树
E. A Simple Task 题目连接: http://www.codeforces.com/contest/558/problem/E Description This task is very ...
- Codeforces Round #590 (Div. 3) D. Distinct Characters Queries(线段树, 位运算)
链接: https://codeforces.com/contest/1234/problem/D 题意: You are given a string s consisting of lowerca ...
- Codeforces Round #292 (Div. 1) C. Drazil and Park 线段树
C. Drazil and Park 题目连接: http://codeforces.com/contest/516/problem/C Description Drazil is a monkey. ...
- Codeforces Round #254 (Div. 1) C. DZY Loves Colors 线段树
题目链接: http://codeforces.com/problemset/problem/444/C J. DZY Loves Colors time limit per test:2 secon ...
随机推荐
- bzoj千题计划281:bzoj4558: [JLoi2016]方
http://www.lydsy.com/JudgeOnline/problem.php?id=4558 容斥原理 全部的正方形-至少有一个点被删掉的+至少有两个点被删掉的-至少有3个点被删掉的+至少 ...
- 一个ssm综合小案例-商品订单管理-第一天
项目需求分析: 功能需求:登录,商品列表查询,修改 项目环境及技术栈: 项目构成及环境: 本项目采用 maven 构建 环境要求: IDEA Version: 2017.2.5 Tomcat Vers ...
- 给定一个整数,求解该整数最少能用多少个Fib数字相加得到
一,问题描述 给定一个整数N,求解该整数最少能用多少个Fib数字相加得到 Fib数列,就是如: 1,1,2,3,5,8,13.... Fib数列,满足条件:Fib(n)=Fib(n-1)+Fib(n- ...
- ASP.NET Web API queryString访问的一点总结
自从开始使用ASP.NET Web API,各种路由的蛋疼问题一直困扰着我,相信大家也都一样. Web API的路由配置与ASP.MVC类似,在App_Start文件夹下,有一个WebApiConfi ...
- Docker学习笔记二 使用镜像
本文地址:https://www.cnblogs.com/veinyin/p/10408363.html Docker运行容器前,需本地存在对应镜像,若没有则Docker从镜像仓库下载该镜像. 镜 ...
- vue需要注意的事宜
1.Vue在进行点击事件的时候大部分是在标签上进行添加的,一般在标签上添加@click: 如果需要在组件上面进行点击事件的时候,直接写@click是木有变化的,需要在后面添加一个.native就如@c ...
- Hibernate的批量查询
Hibernate的查询大致分为以下三种场景, 1. HQL查询-hibernate Query Language(多表查询,但不复杂时使用) 2. Criteria查询(单表条件查询) 3. ...
- linux(CentOS7)中安装erlang(20.3)以及rabbitmq(3.7.9)的步骤以及一些注意事项
首先下载安装包,之后先安装erlang,安装erlang需要很多依赖,所以一步步来: 首先 wxWidgets会报错,这个不是必须的,可以不安装,不影响 然后需要安装一些必须的依赖: yum inst ...
- perl6 中将 字符串 转成十六进制
say Blob.new('abcde'.encode('utf8')).unpack("H*"); say '0x'~'abcde'.encode('utf8').unpack( ...
- 记一次ThreadPoolExecutor面试
ThreadPoolExecutor点滴 线程池应该也是面试绕不开的一个点,平时大家也没少用,但其实也有一些小Tips还是值得记录一下. Constructor public ThreadPoolEx ...