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 ...
随机推荐
- POJ - 2513 Colored Sticks(欧拉通路+并查集+字典树)
https://vjudge.net/problem/POJ-2513 题解转载自:優YoU http://user.qzone.qq.com/289065406/blog/1304742541 题 ...
- 何凯文每日一句打卡||DAY6
- 5个经典的javascript面试问题
问题1:Scope作用范围 考虑下面的代码: (function() { var a = b = 5;})(); console.log(b); 什么会被打印在控制台上? 回答 上面的代码会打印 ...
- [整理]Assembly中的DLL提取
当机器上安装一些程序后,Assembly中的DLL会变得越来越丰富. 拿个常见问题来说明. 安装ReportViewer后其中会出现以下DLL. Microsoft.ReportViewer.Proc ...
- 一组数字,从1到n,从中减少了3个数,顺序打乱,放在n-3的数组里,找出丢失数字
曾经看到有这样一个JS题:有一组数字,从1到n,从中减少了3个数,顺序也被打乱,放在一个n-3的数组里请找出丢失的数字,最好能有程序,最好算法比较快假设n=10000 下面我也来贴一个算法. func ...
- blog迁移
blog迁移到: https://github.com/for-firecat/
- Nuts & Bolts Problem
Given a set of n nuts of different sizes and n bolts of different sizes. There is a one-one mapping ...
- Java继承关系概述
Java中只支持单继承关系 示例代码: package com.java1995; public class People { private String name; private int age ...
- sonarLint--强大的代码审查工具(插件)
idea也有的一个插件 贴上一个eclipse的sonarlint用法 http://blog.csdn.net/limm33/article/details/51166840 不过听说从2015年1 ...
- Heist
CF#509 div2 A 第一次用自己的号打CF祭. 题目描述 昨晚有一家电子商店被抢劫了. 昨天在商店里的所有键盘都是从x开始按升序编号的.例如,如果x=4,并且商店中有3个键盘,那么编号就为4, ...