好像被卡常了,求助
查看原帖
好像被卡常了,求助
368204
ShanQing楼主2023/3/28 22:31
//writer:Oier_szc

#include <bits/stdc++.h>
//#define int long long
using namespace std;
const int mod=1e9+7;
int n,m,a[100005];
struct matrix
{
	int n,m;
	long long a[3][3];
	matrix()
	{
		memset(a,0,sizeof(a));
	}
	matrix operator*(const matrix &W) const
	{
		matrix res;
		res.n=n;
		res.m=W.m;
		for(int i=1;i<=n;++i)
		{
			for(int j=1;j<=W.m;++j)
			{
				for(int k=1;k<=m;++k)
				{
					res.a[i][j]=(res.a[i][j]+a[i][k]*W.a[k][j])%mod;	
				}
			}
		}
		return res; 
	}
};
matrix qwq;
void init()
{
	qwq.n=qwq.m=2;
	qwq.a[1][1]=qwq.a[1][2]=qwq.a[2][1]=1;
}

matrix qpow(matrix base,int b)
{
	matrix res;
	res.n=res.m=base.n;
	for(int i=1;i<=res.n;++i)
	{
		res.a[i][i]=1;
	}
	while(b)
	{
		if(b&1) res=res*base;
		base=base*base;
		b>>=1;
	}
	return res;
}


matrix tree[400005];
matrix tag[400005];
void fa_change(int u)
{
	tree[u].a[1][1]=(tree[u<<1].a[1][1]+tree[u<<1|1].a[1][1])%mod;
	tree[u].a[1][2]=(tree[u<<1].a[1][2]+tree[u<<1|1].a[1][2])%mod;
}
void add(int u,int x)
{
	tag[u]=tag[u]*qpow(qwq,x);
	tree[u]=tree[u]*qpow(qwq,x);
}
bool tag_empty(int u)
{
	return (tag[u].a[1][1]==1)&&(tag[u].a[2][2]==1)&&(tag[u].a[2][1]==0)&&(tag[u].a[1][2]==0);
}
void push_down(int u)
{
	if(tag_empty(u)) return;
	tree[u<<1]=tree[u<<1]*tag[u];
	tree[u<<1|1]=tree[u<<1|1]*tag[u];
	tag[u<<1]=tag[u<<1]*tag[u];
	tag[u<<1|1]=tag[u<<1|1]*tag[u];
	tag[u].a[1][1]=tag[u].a[2][2]=1;
	tag[u].a[1][2]=tag[u].a[2][1]=0;
}
void creattree(int u,int l,int r)
{
	//printf("qwq\n");
	tree[u].n=1;
	tree[u].m=2;
	tag[u].n=2;
	tag[u].m=2;
	tag[u].a[1][1]=tag[u].a[2][2]=1;
	if(l==r)
	{
		if(a[l]==1) tree[u].a[1][1]=1;
		else tree[u].a[1][1]=tree[u].a[1][2]=1;
		if(a[l]>2) tree[u]=tree[u]*qpow(qwq,a[l]-2);
		return;
	}
	int mid=l+r>>1;
	creattree(u<<1,l,mid);
	creattree(u<<1|1,mid+1,r);
	fa_change(u);
}
void update(int u,int l,int r,int L,int R,int x)
{
	if(L<=l&&r<=R)
	{
		add(u,x);
		return;
	}
	push_down(u);
	int mid=l+r>>1;
	if(L<=mid) update(u<<1,l,mid,L,R,x);
	if(R>mid) update(u<<1|1,mid+1,r,L,R,x);
	fa_change(u);
}
long long query(int u,int l,int r,int L,int R)
{
	if(L<=l&&r<=R)
	{
		return tree[u].a[1][1];
	}
	push_down(u);
	int mid=l+r>>1;
	long long res=0;
	if(L<=mid) res=(res+query(u<<1,l,mid,L,R))%mod;
	if(R>mid) res=(res+query(u<<1|1,mid+1,r,L,R))%mod;
	return res;
}
signed main()
{
	init();
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i)
	{
		scanf("%d",&a[i]);
	}
	creattree(1,1,n);
	while(m--)
	{
		int op,l,r,x;
		scanf("%d",&op);
		if(op==1)
		{
			scanf("%d%d%d",&l,&r,&x);
			update(1,1,n,l,r,x);
		}
		else
		{
			scanf("%d%d",&l,&r);
			printf("%d\n",query(1,1,n,l,r));
		}
	}
	return 0;
}

2023/3/28 22:31
加载中...