E.Sasha and Array(线段树+矩阵快速幂)
Posted thusloop
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了E.Sasha and Array(线段树+矩阵快速幂)相关的知识,希望对你有一定的参考价值。
矩阵相乘有分配律和结合律,所以可以用线段树维护斐波那契矩阵的k次方
即矩阵 jz[1][1]=jz[1][2]=jz[2][1]=1;jz[2][2]=0;的k次方
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=8e18;
const int maxn=2e5+100;
const int mod=1e9+7;
int a[maxn];
struct matr
int jz[3][3]= 0;
matr operator *(const matr &tp) const
matr tmp;
for(int i=1; i<=2; i++)
for(int j=1; j<=2; j++)
for(int k=1; k<=2; k++)
tmp.jz[i][j]=(tmp.jz[i][j]+jz[i][k]*tp.jz[k][j])%mod;
return tmp;
matr operator +(const matr &tp)const
matr tmp;
for(int i=1; i<=2; i++)
for(int j=1; j<=2; j++)
tmp.jz[i][j]=(jz[i][j]+tp.jz[i][j])%mod;
return tmp;
;
struct node
int l,r;
//int sum;
int lazy;
matr mat;
t[maxn*4];
matr qpow(int n)
matr b,res;
b.jz[1][1]=b.jz[1][2]=b.jz[2][1]=1;
b.jz[2][2]=0;
for(int i=1; i<=2; i++)res.jz[i][i]=1;
res.jz[1][2]=res.jz[2][1]=0;
//if(n<=0)return res;
while(n)
if(n&1) res=res*b;
b=b*b;
n>>=1;
return res;
void push_up(int k)
if(t[k].l!=t[k].r)
//t[k].sum=(t[k<<1].sum+t[k<<1|1].sum)%mod;
t[k].mat=t[k<<1].mat+t[k<<1|1].mat;
void push_down(int k)
if(t[k].lazy)
t[k<<1].lazy=(t[k<<1].lazy+t[k].lazy);
t[k<<1|1].lazy=(t[k<<1|1].lazy+t[k].lazy);
t[k<<1].mat=t[k<<1].mat*qpow(t[k].lazy);
t[k<<1|1].mat=t[k<<1|1].mat*qpow(t[k].lazy);
//t[k].sum=t[k].mat.jz[1][2]%mod;
t[k].lazy=0;
void build(int l,int r,int k)
t[k].l=l;
t[k].r=r;
if(l==r)
t[k].mat=qpow(a[l]);
//t[k].sum=t[k].mat.jz[1][2]%mod;
return ;
int mid=(l+r)>>1;
build(l,mid,k<<1);
build(mid+1,r,k<<1|1);
push_up(k);
void update(int l,int r,int k,int x)
if(l>t[k].r||r<t[k].l)return ;
if(l<=t[k].l&&t[k].r<=r)
t[k].mat=t[k].mat*qpow(x);
//t[k].sum=(t[k].mat.jz[1][2])%mod;
t[k].lazy=(t[k].lazy+x);
return ;
push_down(k);
update(l,r,k<<1,x);
update(l,r,k<<1|1,x);
push_up(k);
int query(int l,int r,int k)
if(l>t[k].r||r<t[k].l)return 0;
if(l<=t[k].l&&t[k].r<=r)
return t[k].mat.jz[1][2]%mod;
push_down(k);
int ans=0;
ans=(ans+query(l,r,k<<1))%mod;
ans=(ans+query(l,r,k<<1|1))%mod;
return ans%mod;
signed main()
IOS
int n,m;
cin>>n>>m;
for(int i=1; i<=n; i++)
cin>>a[i];
build(1,n,1);
while(m--)
int op,l,r,x;
cin>>op>>l>>r;
if(op==1)
cin>>x;
update(l,r,1,x);
else cout<<query(l,r,1)<<"\\n";
以上是关于E.Sasha and Array(线段树+矩阵快速幂)的主要内容,如果未能解决你的问题,请参考以下文章
CF719E. Sasha and Array [线段树维护矩阵]
CF718C Sasha and Array(线段树维护矩阵)
E. Sasha and Array 矩阵快速幂 + 线段树