代码求调,悬关
查看原帖
代码求调,悬关
671779
__Aha楼主2024/7/8 19:15

P3328

样例死活过不了,各种抽象玩意儿群魔乱舞(强颜欢笑

#include<bits/stdc++.h>
#define mod 1000000007
#define LL long long
using namespace std;
int n,q;
LL A,B,d[300010];
struct matrix
{
	LL o[3][3];
}pl,mi,pl_T,mi_T,v1,v1_T,IM,tr[300010<<2],tagL[300010<<2],tagR[300010<<2];
matrix operator * (const matrix &X,const matrix &Y)
{
	matrix Z;
    for(int i=0;i<=2;i++)
	{
        for(int j=0;j<=2;j++)
		{
			Z.o[i][j]=0;
            for(int k=0;k<=2;k++)
			{
                Z.o[i][j]=(Z.o[i][j]+X.o[i][k]*Y.o[k][j])%mod;
            }
        }
    }
    return Z;
}
matrix operator + (const matrix X,const matrix Y)
{
	matrix Z;
    for(int i=0;i<=2;i++)
	{
        for(int j=0;j<=2;j++)
		{
            Z.o[i][j]=(X.o[i][j]+Y.o[i][j])%mod;
        }
    }
    return Z;
}
matrix mul(matrix X,matrix Y,int s1,int s2,int s3,int s4)
{
	matrix Z;
	memset(Z.o,0,sizeof Z.o);
	for(int i=0;i<=s1;i++)
	{
		for(int j=0;j<=s4;j++)
		{
			Z.o[i][j]=0;
			for(int k=0;k<=s2;k++)
			{
				Z.o[i][j]=(Z.o[i][j]+X.o[i][k]*Y.o[k][j]%mod)%mod;
			}
		}
	}
	return Z;
}
matrix T(matrix X,int s1,int s2)
{
	matrix Z;
	memset(Z.o,0,sizeof Z.o);
	for(int i=0;i<=s1;i++)
	{
		for(int j=0;j<=s2;j++)
		{
			Z.o[i][j]=X.o[j][i];
		}
	}
	return Z;
}
LL quickpow(LL b,LL a)
{
	LL res=1;
	while(a)
	{
		if(a&1) res=res*b%mod;
		b=b*b%mod;
		a>>=1;
	}
	return res%mod;
}
matrix M_quickpow(matrix b,LL a)
{
	matrix res=IM;
	while(a)
	{
		if(a&1) res=res*b;
		b=b*b;
		a>>=1;
	}
	return res;
}
void pushdown(int q)
{
	tagL[q<<1]=tagL[q]*tagL[q<<1];
	tagR[q<<1]=tagR[q<<1]*tagR[q];
	tagL[q<<1|1]=tagL[q]*tagL[q<<1|1];
	tagR[q<<1|1]=tagR[q<<1|1]*tagR[q];
	tr[q<<1]=tagL[q<<1]*tr[q<<1]*tagR[q<<1];
	tr[q<<1|1]=tagL[q<<1|1]*tr[q<<1|1]*tagR[q<<1|1];
	tagL[q]=tagR[q]=IM;
	return;
}
vector<int>fg;
void build(int q,int ql,int qr)
{
	tagL[q]=tagR[q]=IM;
	memset(tr[q].o,0,sizeof tr[q].o);
	if(ql==qr)
	{
		tr[q]=mul(mul(M_quickpow(pl,d[ql-1]-1),v1,2,2,2,0),T(mul(M_quickpow(pl,d[ql+1]-3),v1,2,2,2,0),2,0),2,0,0,2);
//		printf("(%d,%d,%d,%d)\n",ql,qr,tr[q].o[0][0],mul(M_quickpow(pl,d[ql-1]-1),v1,2,2,2,0).o[0][0]);
//		fg.push_back(q);
		return;
	}
	int mid=(ql+qr)>>1;
	build(q<<1,ql,mid);
	build(q<<1|1,mid+1,qr);
	tr[q]=tr[q<<1]+tr[q<<1|1];
//	printf("(%d,%d,%d)\n",ql,qr,tr[q].o[0][0]);
	return;
}
void update(int q,int ql,int qr,int l,int r,matrix LM,matrix RM)
{
//	printf("(%d,%d,%d)\n",ql,qr,tr[q].o[0][0]);
	if(l<=ql&&qr<=r)
	{
		tagL[q]=LM*tagL[q];
		tagR[q]=tagR[q]*RM;
		tr[q]=tagL[q]*tr[q]*tagR[q];	
		return;
	}
	pushdown(q);
	int mid=(ql+qr)>>1;
	if(l<=mid) update(q<<1,ql,mid,l,r,LM,RM);
	if(r>mid) update(q<<1|1,mid+1,qr,l,r,LM,RM);
	tr[q]=tr[q<<1]+tr[q<<1|1];
	return;
}
int query(int q,int ql,int qr,int l,int r)
{
// 	printf("(%d,%d,%d)\n",ql,qr,tr[q].o[0][0]);
	if(l<=ql&&qr<=r)
	{
		return tr[q].o[0][0]%mod;
	}
	pushdown(q);
	int mid=(ql+qr)>>1;
	LL t1=0,t2=0;
	if(l<=mid) t1=query(q<<1,ql,mid,l,r);
	if(r>mid) t2=query(q<<1|1,mid+1,qr,l,r);
	return (t1+t2)%mod;
}
void init()
{
	memset(pl.o,0,sizeof pl.o);
	memset(pl_T.o,0,sizeof pl_T.o);
	memset(mi.o,0,sizeof mi.o);
	memset(mi_T.o,0,sizeof mi_T.o);
	memset(v1.o,0,sizeof v1.o);
	memset(v1_T.o,0,sizeof v1_T.o);
	memset(IM.o,0,sizeof IM.o);
	pl.o[0][0]=pl.o[1][0]=pl.o[2][2]=1;
	pl.o[0][1]=A;
	pl.o[0][2]=B;
	if(A)
	{
		LL tmp=quickpow(A,mod-2);
		mi.o[0][1]=mi.o[2][2]=1;
		mi.o[1][0]=tmp;
		mi.o[1][1]=mod-tmp;
		mi.o[1][2]=mod-tmp*B%mod;
	}
	else
	{
		mi.o[0][1]=mi.o[1][1]=mi.o[2][2]=1;
		mi.o[1][2]=mod-B;
	}
	v1.o[1][0]=v1.o[2][0]=1;
	v1.o[0][0]=2;
	IM.o[0][0]=IM.o[1][1]=IM.o[2][2]=1;
	pl_T=T(pl,2,2);
	mi_T=T(mi,2,2);
	v1_T=T(v1,2,0);
	return;
}
int main()
{
	cin>>n>>q>>A>>B;
	init();
	for(int i=1;i<=n;i++) 
	{
		cin>>d[i];
	}
	build(1,2,n-1);
	char op[10];
	int x,y;
	while(q--)
	{
		cin>>op>>x>>y;
		if(op[0]=='p')
		{
			update(1,2,n-1,x+1,min(y+1,n-1),pl,IM);
			update(1,2,n-1,max(x-1,2),y-1,IM,pl_T);
		}
		else if(op[0]=='m')
		{
			update(1,2,n-1,x+1,min(y+1,n-1),mi,IM);
			update(1,2,n-1,max(x-1,2),y-1,IM,mi_T);
		}
		else
		{
			cout<<query(1,2,n-1,x+1,y-1)<<endl;
		}
	}
//	1 a b   2
//	1 0 0   1
//	0 0 1   1
	return 0;
}
2024/7/8 19:15
加载中...