• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

【CF 718C】fibonacci

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

题意

  给你一个长度为 \(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;
}

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
c++中的.hpp文件发布时间:2022-07-13
下一篇:
C# For Bot Framework发布时间:2022-07-13
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap