/*
题意:给定一个长度为n的序列a。
两种操作:
1.给定区间l r 加上某个数x.
2.查询区间l r sigma(fib(ai)) fib代表斐波那契数列。
思路:
1.矩阵操作,由矩阵快速幂求一个fib数根据矩阵的乘法结合率,A*C+B*C=(A+B)*C; 这样可以通过线段树维护某个区间2*1矩阵的和。
2.时限卡的紧...用我的矩阵乘法板子TLE了。所以把板子里边的三重循环改成手工公式...
3.注意(a+b)%mod。这种,改成if(a+b>=mod)a+b-mod这种形式时间几乎减半了==...(因为查询和更新操作每次都要把两个矩阵加起来...所以这种优化在这题来说作用明显)
4.注意lazy标记不要记录要乘多矩阵多少次方...而是直接记录该矩阵...这是最重要的一个优化(个人认为).因为每次向下层更新都要求一次矩阵...
*/
#include<bits/stdc++.h>
#define N 100020
#define MAXS 2
using namespace std;
long long jilu[N];
long long jil[N];
long long MOD =1e9+;
struct Matrix
{
long long mx[MAXS][MAXS];
Matrix()
{
memset(mx,,sizeof(mx));
}
Matrix operator* (const Matrix& b) const
{
Matrix tmp;
tmp.mx[][]=mx[][]*b.mx[][]+mx[][]*b.mx[][];
if(tmp.mx[][]>=MOD)tmp.mx[][]%=MOD;
tmp.mx[][]=mx[][]*b.mx[][]+mx[][]*b.mx[][];
if(tmp.mx[][]>=MOD)tmp.mx[][]%=MOD;
tmp.mx[][]=mx[][]*b.mx[][]+mx[][]*b.mx[][];
if(tmp.mx[][]>=MOD)tmp.mx[][]%=MOD;
tmp.mx[][]=mx[][]*b.mx[][]+mx[][]*b.mx[][];
if(tmp.mx[][]>=MOD)tmp.mx[][]%=MOD;
return tmp;
} Matrix operator +(const Matrix &b)const{
Matrix tmp;
for(int i=;i<;i++){
for(int j=;j<;j++){
tmp.mx[i][j]=(mx[i][j]+b.mx[i][j]);
if(tmp.mx[i][j]>=MOD)tmp.mx[i][j]-=MOD;
}
}
return tmp;
}
void initE()
{
memset(mx,, sizeof(mx));
for (int i= ; i< ; i++)
{
mx[i][i]=;
}
} Matrix mpow(long long k)
{
Matrix c,b;
c=(*this); b.initE();
while(k)
{
if(k&)
{
b=b*c;
}
c=c*c;
k>>=;
}
return b;
}
};
Matrix biao,ben;
struct tr{
Matrix val,tt;
long long aa;
int s,e;
};
tr tree[<<];
void build(int s,int e,int k){
tr &tmp=tree[k];
tmp.s=s;tmp.e=e;tmp.aa=;
tmp.tt.initE();
if(s==e){
tmp.val.mx[][]=jilu[s];
tmp.val.mx[][]=jil[s];
return;
}
int mid=(s+e)>>;
build(s,mid,k<<);
build(mid+,e,k<<|);
tmp.val=tree[k<<].val+tree[k<<|].val;
}
void add(int s,int e,int k,int num){
tr &tmp=tree[k];
if(s==tmp.s&&e==tmp.e){
Matrix ttt=biao.mpow(num);
tmp.tt=ttt*tmp.tt;
tmp.val=ttt*tmp.val;
tmp.aa+=num;
return;
}
if(tmp.aa){
tree[k<<].aa+=tmp.aa;
tree[k<<].val=tmp.tt*tree[k<<].val;
tree[k<<].tt=tmp.tt*tree[k<<].tt;
tree[k<<|].aa+=tmp.aa;
tree[k<<|].val=tmp.tt*tree[k<<|].val;
tree[k<<|].tt=tmp.tt*tree[k<<|].tt;
tmp.tt.initE();
tmp.aa=;
}
int mid=(tmp.s+tmp.e)>>;
if(e<=mid)add(s,e,k<<,num);
else if(s>mid)add(s,e,k<<|,num);
else{
add(s,mid,k<<,num);
add(mid+,e,k<<|,num);
}
tmp.val=tree[k<<].val+tree[k<<|].val;
}
long long query(int s,int e,int k){
tr &tmp=tree[k];
if(tmp.s==s&&tmp.e==e){
return tmp.val.mx[][];
}
if(tmp.aa){
tree[k<<].aa+=tmp.aa;
tree[k<<].val=tmp.tt*tree[k<<].val;
tree[k<<].tt=tmp.tt*tree[k<<].tt;
tree[k<<|].aa+=tmp.aa;
tree[k<<|].val=tmp.tt*tree[k<<|].val;
tree[k<<|].tt=tmp.tt*tree[k<<|].tt;
tmp.tt.initE();
tmp.aa=;
}
int mid=(tmp.s+tmp.e)>>;
if(e<=mid)return query(s,e,k<<);
else if(s>mid)return query(s,e,k<<|);
else return (query(s,mid,k<<)+query(mid+,e,k<<|))%MOD;
}
int main()
{
int n,m;
biao.mx[][]=biao.mx[][]=biao.mx[][]=;
ben.mx[][]=ben.mx[][]=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++){
scanf("%lld",jilu+i);
if(jilu[i]==){
jil[i]=;
}
else if(jilu[i]==){
jilu[i]=;
jil[i]=;
}
else{
Matrix rel=biao.mpow(jilu[i]-)*ben;
jilu[i]=rel.mx[][];
jil[i]=rel.mx[][];
}
}
build(,n,);
for(int i=;i<=m;i++){
int typ,l,r,x;
scanf("%d",&typ);
if(typ==){
scanf("%d%d%d",&l,&r,&x);
add(l,r,,x);
}
else{
scanf("%d%d",&l,&r);
printf("%lld\n",query(l,r,));
}
}
}

Codeforces 719E [斐波那契区间操作][矩阵快速幂][线段树区间更新]的更多相关文章

  1. HDU 4549 M斐波那契数列(矩阵快速幂)

    题目链接:M斐波那契数列 题意:$F[0]=a,F[1]=b,F[n]=F[n-1]*F[n-2]$.给定$a,b,n$,求$F[n]$. 题解:暴力打表后发现$ F[n]=a^{fib(n-1)} ...

  2. CodeForces - 450B Jzzhu and Sequences —— 斐波那契数、矩阵快速幂

    题目链接:https://vjudge.net/problem/CodeForces-450B B. Jzzhu and Sequences time limit per test 1 second ...

  3. M斐波那契数列(矩阵快速幂+费马小定理)

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

  4. HDU 4549 M斐波那契数列(矩阵快速幂+费马小定理)

    M斐波那契数列 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submi ...

  5. 洛谷P1349 广义斐波那契数列(矩阵快速幂)

    P1349 广义斐波那契数列 https://www.luogu.org/problemnew/show/P1349 题目描述 广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列.今给定 ...

  6. HDU——4549M斐波那契数列(矩阵快速幂+快速幂+费马小定理)

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Total Su ...

  7. P1962 斐波那契数列 【矩阵快速幂】

    一.题目 P1962 斐波那契数列 二.分析 比较基础的递推式转换为矩阵递推,这里因为$n$会超出$int$类型,所以需要用矩阵快速幂加快递推. 三.AC代码 1 #include <bits/ ...

  8. 【洛谷P1962 斐波那契数列】矩阵快速幂+数学推导

    来提供两个正确的做法: 斐波那契数列双倍项的做法(附加证明) 矩阵快速幂 一.双倍项做法 在偶然之中,在百度中翻到了有关于斐波那契数列的词条(传送门),那么我们可以发现一个这个规律$ \frac{F_ ...

  9. [luoguP1962] 斐波那契数列(矩阵快速幂)

    传送门 解析详见julao博客连接 http://worldframe.top/2017/05/10/清单-数学方法-——-矩阵/ ——代码 #include <cstdio> #incl ...

随机推荐

  1. JavaWeb Chapter 7 监听器

    1.  监听器Session.request.context对象属性的变化: 2.  三个对象都有生命周期和属性改变的监听: 3.  Session另外还有会话迁移和对象绑定的监听: 4.  Sess ...

  2. 删除Windows 服务

    删除的办法有两个: 办法一: 用sc.exe这个Windows命令 开始--运行--cmd.exe,然后输入sc就可以看到了.使用办法很简单: sc delete “服务名” (如果服务名中间有空格, ...

  3. Windows 下java环境变量的配置(Windows7 ,8,8.1,10)

    Windows 下java环境变量的配置 在“系统”面板的左上角选择“高级系统设置”,在弹出的系统属性中选择”高级“项,然后点击右下角的“环境变量(N)...”,就此进入JAVA环境变量的配置. 如果 ...

  4. BaiduMap Search List

    using AnfleCrawler.Common; using HtmlClient; using System; using System.Collections.Generic; using S ...

  5. Android RadioGroup 及资源文件 & selector

    RadioGroup :单选组         RadioButton :单选按钮 RadioButton和CheckBox的区别: 1.单个RadioButton在选中后,通过点击无法变为未选中 单 ...

  6. .net 后台读取pdf的值

    在网上找了内容 下载了这个插件 引用在了项目中 然后找到pdf中的位置 进行读取 string pdfPath = Server.MapPath("~/ViewPatPdf.pdf" ...

  7. WCF 服务器调用回调函数 单程-双程操作模式:(待补充Demo)

    服务器端Server 实现回调接口Interface定义.客户端实现回调接口Interface实现,从而实现服务器端通过  var channel = OperationContent.Current ...

  8. select、poll、poll的比较(转)

    原文地址:http://www.cnblogs.com/xuxm2007/archive/2011/08/15/2139809.html select.poll.epoll的比较 linux提供了se ...

  9. 如何快速编写Vim语法高亮文件

    这里有一份中文的入门文档,但是太长了,不想读,所以有本文 最快的办法,就是找一个语法相近的语法高亮文件,稍微改一下 自己从头写的话,首先搞定关键字: syntax case match "是 ...

  10. A candidate solution for Java Web Application - current session

    Motivation Do it once, resue for ever. Audience myself, Java Web developers Scope 应用案例 图书借阅系统 阶段1需求: ...