萌新求助 wa on #10
查看原帖
萌新求助 wa on #10
520056
luoyx楼主2023/5/18 14:29

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
int n,m;
int a[N];
int op,l,r,x;
const int mod=1e9+7;

struct matrix{
	int m[4][4];
	void clear(){
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				m[i][j]=0;
			}
		}
	}
	void init(){
		clear();
		for(int i=0;i<4;i++){
			m[i][i]=1;
		}
	}
	friend matrix operator *(matrix a,matrix b){
		matrix z; z.clear();
		for(int i=1;i<4;i++){
			for(int j=1;j<4;j++){
				for(int k=1;k<4;k++){
					z.m[i][j]=(a.m[i][k]*b.m[k][j]%mod+z.m[i][j])%mod;
				}
			}
		}
		return z;
	}
	friend matrix operator +(matrix a,matrix b){
		matrix z; z.clear();
		for(int i=1;i<4;i++){
			for(int j=1;j<4;j++){
				z.m[i][j]=(a.m[i][j]+b.m[i][j])%mod;
			}
		}
		return z;
	}
}F;

matrix qp(matrix a,int k){
	matrix b;
	b.init();
	while(k){
		if(k&1) b=b*a;
		a=a*a;
		k>>=1;
	}
	return b;
}

int rt,cnt,lc[N],rc[N];

struct node{
	matrix sum,lt;
}tr[N<<2];

void pushup(int p){
	tr[p].sum=tr[lc[p]].sum+tr[rc[p]].sum;
}

void build(int &p,int l,int r){
	p=++cnt;
	tr[p].lt.init();
	tr[p].sum.clear();
	if(l==r){
		matrix h;
		h.clear();
		h.m[1][1]=h.m[1][2]=1;
		tr[p].sum=h*qp(F,a[l]-1);
		return ;
	}
	int m=l+r>>1;
	build(lc[p],l,m);
	build(rc[p],m+1,r);
	pushup(p);
}

void pushdown(int p){
	tr[lc[p]].sum=tr[lc[p]].sum*tr[p].lt;
	tr[rc[p]].sum=tr[rc[p]].sum*tr[p].lt;
	tr[lc[p]].lt=tr[lc[p]].lt*tr[p].lt;
	tr[rc[p]].lt=tr[rc[p]].lt*tr[p].lt;
	tr[p].lt.init();
}

void upd(int p,int L,int R,matrix y){
	if(l<=L&&R<=r){
		tr[p].sum=tr[p].sum*y;
		tr[p].lt=tr[p].lt*y;
		return ;
	}
	pushdown(p);
	int m=L+R>>1;
	if(m>=l) upd(lc[p],L,m,y);
	if(m<r) upd(rc[p],m+1,R,y);
	pushup(p);
}

matrix query(int p,int L,int R){
	if(l<=L&&R<=r) return tr[p].sum;
	pushdown(p);
	int m=L+R>>1;
	matrix ans; ans.clear();
	if(m>=l) ans=ans+query(lc[p],L,m);
	if(m<r) ans=ans+query(rc[p],m+1,R);
	return ans; 
}

signed main(){
	cin>>n>>m;
	F.clear();
	F.m[2][2]=F.m[1][2]=F.m[2][1]=1;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	build(rt,1,n);
	while(m--){
		cin>>op>>l>>r;
		if(op==1){
			cin>>x;
			matrix y;
			y=qp(F,x);
			upd(rt,1,n,y);
		}
		else{
			matrix ans=query(rt,1,n);
			cout<<ans.m[1][1]%mod<<endl;
		}
	}
}
2023/5/18 14:29
加载中...