题意

  给你一个长度为 \(n\) 的序列 \(a\),有 \(m\) 次操作,操作分两种

  • \(\text{1}\space \text{l}\space \text{r}\space \text{x}\)、区间加;
  • \(\text{2}\space \text{l}\space \text{r}\)、求 \(\sum\limits_{i=l}^{r} \text{fib}(a_i) \mod (10^9+7)\)

  \(\text{fib}(i)\) 表示斐波那契数列第 \(i\) 项,初始值为 \(\text{fib}(1)=\text{fib}(2)=1\)。

  \(n,m\le 10^5,\space x,a_i\le 10^9\)

题解

  shabi 模板题,我考试的时候弱智了,十点钟杠 T3 的时候才突然想到这是个线段树维护矩阵的模板题,我他吗前两个小时在睡觉吗

  最后 T3 的 150 行代码 A 了,这个 T1 没写完……考后过编译就过了样例,然后交上去 1A 了……

  CaO.jpg

  好吧这可能不叫题解,但我觉得这种 shabi 题好像不用写题解吧。

#include<bits/stdc++.h>
#define ll long long
#define N 100010
#define mod 1000000007
using namespace std;
inline int read(){
int x=0; bool f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
for(; isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
if(f) return x;
return 0-x;
}
int n,m;
struct Matrix{
int x[2][2];
Matrix(){x[0][0]=x[1][1]=1, x[0][1]=x[1][0]=0;}
Matrix operator + (const Matrix &a)const{
Matrix ret=Matrix();
ret.x[0][0] = (x[0][0] + a.x[0][0]) % mod;
ret.x[0][1] = (x[0][1] + a.x[0][1]) % mod;
return ret;
}
Matrix operator * (const Matrix &a)const{
Matrix ret=Matrix(); int i,j,k;
for(i=0; i<2; ++i)
for(int j=0; j<2; ++j)
ret.x[i][j] = ((ll)x[i][0]*a.x[0][j]%mod + (ll)x[i][1]*a.x[1][j]%mod) % mod;
return ret;
}
bool operator != (const Matrix &a)const{
return x[0][0]!=a.x[0][0] || x[0][1]!=a.x[0][1] || x[1][0]!=a.x[1][0] || x[1][1]!=a.x[1][1];
}
}a[N],A,B,mul;
Matrix matPow(Matrix x, int y){
Matrix ret=Matrix();
while(y){
if(y&1) ret=ret*x;
x=x*x;
y>>=1;
}
return ret;
}
namespace SegTree{
#define ls o<<1
#define rs o<<1|1
struct Tree{Matrix sum,tag;}tr[N<<2];
inline void pushup(int o){
tr[o].sum=tr[ls].sum+tr[rs].sum;
//cout<<"pushup:"<<tr[ls].sum.x[0][0]<<' '<<tr[ls].sum.x[0][1]<<' '<<tr[rs].sum.x[0][0]<<' '<<tr[rs].sum.x[0][1]<<endl;
//cout<<"pushup:"<<tr[o].sum.x[0][0]<<' '<<tr[o].sum.x[0][1]<<endl;
}
inline void pushdown(int o){
if(tr[o].tag!=Matrix()){
tr[ls].sum=tr[ls].sum*tr[o].tag, tr[rs].sum=tr[rs].sum*tr[o].tag;
tr[ls].tag=tr[ls].tag*tr[o].tag, tr[rs].tag=tr[rs].tag*tr[o].tag;
tr[o].tag=Matrix();
}
}
void build(int o, int l, int r){
if(l==r){tr[o].sum=a[l], tr[o].tag=Matrix(); return;}
int mid=l+r>>1;
build(ls,l,mid), build(rs,mid+1,r);
pushup(o);
}
void mdf(int o, int l, int r, int L, int R){
if(L<=l && r<=R){
tr[o].sum=tr[o].sum*mul;
tr[o].tag=tr[o].tag*mul;
return;
}
pushdown(o);
int mid=l+r>>1;
if(L<=mid) mdf(ls,l,mid,L,R);
if(R>mid) mdf(rs,mid+1,r,L,R);
pushup(o);
}
void mdf(int l, int r){
mdf(1,1,n,l,r);
}
int query(int o, int l, int r, int L, int R){
if(L<=l && r<=R) return tr[o].sum.x[0][1];
pushdown(o);
int mid=l+r>>1, ret=0;
if(L<=mid) ret=ret+query(ls,l,mid,L,R);
if(R>mid) ret=ret+query(rs,mid+1,r,L,R);
return ret%mod;
}
int query(int l, int r){
return query(1,1,n,l,r);
}
#undef ls
#undef rs
}using namespace SegTree;
int main(){
n=read(), m=read();
A.x[0][0]=1, A.x[0][1]=0;
B.x[0][0]=B.x[0][1]=B.x[1][0]=1, B.x[1][1]=0;
Matrix C=Matrix()*A;
for(int i=1; i<=n; ++i) a[i]=A*matPow(B,read());
build(1,1,n);
int opt,l,r;
for(int i=1; i<=m; ++i){
opt=read(), l=read(), r=read();
if(opt==1){
mul=matPow(B,read());
mdf(l,r);
}
else printf("%d\n",query(l,r));
}
return 0;
}

【CF 718C】fibonacci的更多相关文章

  1. 1643【例 3】Fibonacci 前 n 项和

    1643:[例 3]Fibonacci 前 n 项和 时间限制: 1000 ms         内存限制: 524288 KB sol:这题应该挺水的吧,就像个板子一样 1 0 01 1 0   * ...

  2. 一本通1642【例 2】Fibonacci 第 n 项

    1642: [例 2]Fibonacci 第 n 项 sol:挺模板的吧,经典题吧qaq (1) 1 0    *     1 1     =   1 1 1 0 (2) 1 1    *     1 ...

  3. 【CF#338D】GCD Table

    [题目描述] 有一张N,M<=10^12的表格,i行j列的元素是gcd(i,j) 读入一个长度不超过10^4,元素不超过10^12的序列a[1..k],问是否在某一行中出现过 [题解] 要保证g ...

  4. 【hdu 1848】Fibonacci again and again

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s) ...

  5. 【CF#303D】Rotatable Number

    [题目描述] Bike是一位机智的少年,非常喜欢数学.他受到142857的启发,发明了一种叫做“循环数”的数. 如你所见,142857是一个神奇的数字,因为它的所有循环排列能由它乘以1,2,...,6 ...

  6. 【POJ 3070】 Fibonacci

    [题目链接]            点击打开链接 [算法]           矩阵乘法快速幂 [代码] #include <algorithm> #include <bitset& ...

  7. 【HDU 2855】 Fibonacci Check-up (矩阵乘法)

    Fibonacci Check-up Problem Description Every ALPC has his own alpc-number just like alpc12, alpc55, ...

  8. 【CF 463F】Escape Through Leaf

    题意 给你一棵 \(n\) 个点的树,每个节点有两个权值 \(a_i,b_i\). 从一个点 \(u\) 可以跳到以其为根的子树内的任意一点 \(v\)(不能跳到 \(u\) 自己),代价是 \(a_ ...

  9. 【CF 453A】 A. Little Pony and Expected Maximum(期望、快速幂)

    A. Little Pony and Expected Maximum time limit per test 1 second memory limit per test 256 megabytes ...

随机推荐

  1. 从 ssh private key 中重新生成 public key

    Use the -y option to ssh-keygen: ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub From the 'man ...

  2. 在Linux中使用minikube

    Minikebe Minikube是一个轻量级Kubernetes实现,它在本地机器上创建一个VM,并部署一个只包含一个节点的简单集群. Minikube使用Docker机器来管理Kubernetes ...

  3. (2)网络基础之IP

    IP分为IPV4和IPV6. 以下只讲IPV4,IPV6后期会重新分出来 (以下均为个人理解,如果有误,欢迎提出.也希望如果转载,能通知我并注明转载信息,毕竟字也是我一个个码出来的.谢谢) IPV4地 ...

  4. python高级篇

    1.切片功能:类似于java中的split方法.对list或者triple中几个值进行取出的过程. L = ['a','b','c','d']   L[0:3] = ['a','b','c']   # ...

  5. windows使用放大镜快速放大屏幕局部

    Win10系统自带放大镜有时真的是比较难使用的,但是如果你对他的快捷键有所了解之后就会感觉它其实也没有那么难,用户可以在使用完之后直接按快捷键将其关闭,一起看看吧. Win10系统放大镜快速关闭快捷键 ...

  6. Linux C/C++基础——二级指针做形参

    1.二级指针做形参 #include<stdio.h> #include<stdlib.h> void fun(int **temp) { *temp=(int*)malloc ...

  7. Python pip升级及升级失败解决方案

    本教程用于Python  pip升级及失败解决方案 首先查看脚本 pip show pip 我已经升级到了最新的版本 安装其他模块过程中出现下面提示,便说明你需要升级pip You are using ...

  8. C#实现多线程的方式:使用Parallel类

    简介 在C#中实现多线程的另一个方式是使用Parallel类.  在.NET4中 ,另一个新增的抽象线程是Parallel类 .这个类定义了并行的for和foreach的 静态方法.在为 for和 f ...

  9. VS2008新增文件没有模板

    可能是我安装的过程中发神经没有选中选项什么的,打开来想建个项目发现一个模板都没有,那就很尴尬了,作为对开发工具极度依赖的人,这真的难受... 在网上找到别人的办法 开始 –> 程序 –> ...

  10. 旗舰版win7系统中GraphEdit执行Loading a Graph From an External Process失败对策

    操作系统:旗舰版win7 DirectShow SDK: 9.0 IDE环境:VS2008 以下代码参考MSDN: HRESULT AddToRot(IUnknown *pUnkGraph, DWOR ...