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;
}