zoukankan      html  css  js  c++  java
  • 【CF 718C】fibonacci

    题意

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

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

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

      (n,mle 10^5,space x,a_ile 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
    ",query(l,r));
    	}
    	return 0;
    }
    
  • 相关阅读:
    oracle unwrap解密工具
    介绍一款国产的矢量图形设计软件--百绘大师
    windows10上安装OpenSSL_1.1.1d_x64
    centos7上安装phantomjs并对页面截屏
    如何用Java Socket实现一个简单的Redis客户端
    cenos上通过yum安装mariadb
    windows上杀掉指定名称的进程
    centos磁盘满时查找大文件清理掉
    为Vertica数据库增加自定义函数to_base64和from_base64
    解决Vertica集群某节点出现Clock skewed告警
  • 原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/cf373c.html
Copyright © 2011-2022 走看看