CodeForces 719E Sasha and Array 【线段树】【快速矩阵幂】
来源:互联网 发布:unity3d 刚体穿透 编辑:程序博客网 时间:2024/05/22 12:59
题目:点击打开链接
题意:给出有n个元素的数列ai(1<=i<=n)以及m次操作,操作分为两种:①将区间[l,r]的数加x;②询问∑f(ai)(l<=i<=r),其中f(x)是斐波那契数列的第x个数
分析:容易想到用快速矩阵幂求斐波那契数列,同时用线段树储存和矩阵以及lazy矩阵,如果lazy标记为指数的话每次更新都要用一遍快速矩阵幂,就会超时。因为矩阵乘法满足分配律,且区间[l,r]加上x可以表示为乘上x次q矩阵,所以线段树维护矩阵之和,同时每次更新的时候,x可以先用快速矩阵幂,求出变换x次后的矩阵,然后在线段树中更新,即和矩阵和lazy矩阵乘上该矩阵,表示加上区间的数加上x后的斐波那契数之和了。
#pragma comment(linker, "/STACK:1024000000,1024000000")#include <stdio.h>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <set>#include <vector>#include <map>#define sqr(x) ((x)*(x))#define PR pair<int,int>#define MP make_pair#define fi first#define se second#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define ll long longconst ll INF = 3e18;const int inf=0x3f3f3f3f;const int M=100010;const int N=100010;const int Matsize=2;const ll MOD=1000000007;const double eps=1e-3;const double pi=acos(-1.0);using namespace std;struct Mat{ ll mat[Matsize][Matsize]; void init() { for(int i=0;i<Matsize;i++) { for(int j=0;j<Matsize;j++) mat[i][j]=0; mat[i][i]=1; } } Mat operator*(const Mat &t)const { Mat ans; memset(ans.mat,0,sizeof(ans.mat)); for(int k=0;k<Matsize;k++) for(int i=0;i<Matsize;i++) for(int j=0;j<Matsize;j++) ans.mat[i][j]=(ans.mat[i][j]+mat[i][k]*t.mat[k][j])%MOD; return ans; } Mat operator+(const Mat &t)const { Mat ans; for(int i=0;i<Matsize;i++) for(int j=0;j<Matsize;j++) ans.mat[i][j]=(mat[i][j]+t.mat[i][j])%MOD; return ans; }};int n,m,op,l,r;Mat a[N<<2],lazy[N<<2],mt;ll x;Mat pow_M(ll m){ Mat res; res.init(); mt.mat[0][0]=mt.mat[0][1]=mt.mat[1][0]=1,mt.mat[1][1]=0; while(m) { if(m&1) res=res*mt; mt=mt*mt; m>>=1; } return res;}void pushup(int rt){ a[rt]=a[rt<<1]+a[rt<<1|1];}void pushdown(int rt){ lazy[rt<<1]=lazy[rt<<1]*lazy[rt]; lazy[rt<<1|1]=lazy[rt<<1|1]*lazy[rt]; a[rt<<1]=a[rt<<1]*lazy[rt]; a[rt<<1|1]=a[rt<<1|1]*lazy[rt]; lazy[rt].init();}void build(int l,int r,int rt){ a[rt].init(); lazy[rt].init(); if(l==r) { ll t; scanf("%I64d",&t); a[rt]=pow_M(t-1); return; } int m=l+r>>1; build(lson); build(rson); pushup(rt);}void update(int L,int R,Mat x,int l,int r,int rt){ if(L<=l&&r<=R) { a[rt]=a[rt]*x; lazy[rt]=lazy[rt]*x; return; } pushdown(rt); int m=l+r>>1; if(L<=m) update(L,R,x,lson); if(m<R) update(L,R,x,rson); pushup(rt);}ll query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R) return a[rt].mat[0][0]; pushdown(rt); int m=l+r>>1; ll res=0; if(L<=m) res=(res+query(L,R,lson))%MOD; if(m<R) res=(res+query(L,R,rson))%MOD; return res;}int main(){ scanf("%d%d",&n,&m); build(1,n,1); while(m--) { scanf("%d",&op); if(op==1) { scanf("%d%d%I64d",&l,&r,&x); Mat t=pow_M(x); update(l,r,t,1,n,1); } else { scanf("%d%d",&l,&r); printf("%I64d\n",query(l,r,1,n,1)); } }}
0 0
- [Codeforces 719 E. Sasha and Array] 矩阵快速幂+线段树
- CodeForces-719E Sasha and Array(线段树+矩阵快速幂)
- 【CodeForces 719E】【线段树+矩阵快速幂】 Sasha and Array
- CodeForces 719E Sasha and Array 【线段树】【快速矩阵幂】
- CodeForces - 719E Sasha and Array 线段树 + 矩阵快速幂
- 【Codeforces 718C&719E】Sasha and Array【线段树成段更新+矩阵快速幂】
- cf/Codeforces Round #373 div1-C/div2-E Sasha and Array 线段树 + 维护矩阵快速幂
- [codeforces] 719E Sasha and Array 线段树+快速斐波那契
- 线段树+矩阵快速幂 codeforces718C Sasha and Array
- Codeforces Round #373 (Div. 2) E. Sasha and Array 线段树维护矩阵
- E. Sasha and Array——矩阵+线段树
- Codeforces 718C Sasha and Array(线段树维护矩阵)
- codeforces 373div1 Sasha and Array 矩阵+线段树
- CodeForces 718C Sasha and Array(矩阵类+线段树)
- Codeforces Round #373 (Div. 2) E. Sasha and Array
- Codeforces Round #373 (Div. 2) E. Sasha and Array
- codeforces #373(div 2) E (线段树+矩阵快速幂)
- Codeforces 718C C. Sasha and Array
- Google官方MVP+Dagger2架构详解----非常详细,值得多看几遍(okhttp cache)
- ELK5.0日志分析平台搭建+Beats
- 直线围成的三角形数
- 链表中倒数第k个节点
- 蓝牙ble实现空中升级功能
- CodeForces 719E Sasha and Array 【线段树】【快速矩阵幂】
- Hbase协处理器(Coprocessor)
- 自学iOS开发系列----C语言(数组)
- java.security.InvalidKeyException: Illegal key size
- java获取当前时间
- 欧拉函数,筛法(最大公约数之和——极限版II,UVA 11426)
- linux系统下安装 jdk、tomcat、jetty 总结
- 注解的方式配置springMVC
- 11月17日——离noip还有2天[绯弹的亚里亚]