既然要交换AB,那就在线段树中把两种矩阵都存下来好了
然后swap( c[ rt ][ 0 ],c[ rt ][ 1 ] )。
int n,q;
char s[MAXN];
struct M
{
ll m[2][2];
M(){mem(m,0);}
}A,B;
M mul(M a, M b)
{
M ans;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
ans.m[i][j] = (ans.m[i][j] + a.m[i][k] * b.m[k][j] % mod) % mod;
return ans;
}
struct Segment_Tree
{
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
M c[MAXN<<2][2];
int lazy[MAXN<<2];
inline int ls(int p) {return p<<1;}
inline int rs(int p) {return p<<1|1;}
void push_up(int p)
{
c[p][0]=mul(c[ls(p)][0],c[rs(p)][0]);
c[p][1]=mul(c[ls(p)][1],c[rs(p)][1]);
}
void push_down(int p)
{
swap(c[ls(p)][0],c[ls(p)][1]);
swap(c[rs(p)][0],c[rs(p)][1]);
lazy[ls(p)]^=lazy[p];
lazy[rs(p)]^=lazy[p];
lazy[p]=0;
}
void build(int rt,int l,int r)
{
lazy[rt]=0;
if(l==r)
{
if(s[l]=='A') c[rt][0]=A,c[rt][1]=B;
else c[rt][0]=B,c[rt][1]=A;
return;
}
int mid = (l+r)>>1;
build(lson);build(rson);
push_up(rt);
}
void Query(int ql,int qr,int rt,int l,int r,M & ans)
{
if(ql<=l && r<=qr)
{
ans=mul(ans,c[rt][0]);
return;
}
if(lazy[rt]) push_down(rt);
int mid=(l+r)>>1;
if(ql<=mid) Query(ql,qr,lson,ans);
if(qr>mid) Query(ql,qr,rson,ans);
return ;
}
void update(int ql,int qr,int rt,int l,int r)//区间更新
{
if(ql<=l && qr>=r) {lazy[rt]^=1;swap(c[rt][0],c[rt][1]);return;}
if(lazy[rt]) push_down(rt);
int mid=(l+r)>>1;
if(ql<=mid) update(ql,qr,lson);
if(qr>mid) update(ql,qr,rson);
push_up(rt);
}
}tree;
int main()
{
rd(n),rd(q);
scanf("%s",s+1);
A.m[0][0] = A.m[1][0] = A.m[1][1] = B.m[0][0] = B.m[0][1] = B.m[1][1] = 1;
tree.build(1,1,n);
while(q--)
{
int op;rd(op);
if(op==1)
{
int l,r;rd(l),rd(r);
tree.update(l,r,1,1,n);
}
else
{
int l,r,a,b;
rd(l),rd(r),rd(a),rd(b);
M ans,base;
ans.m[0][0]=ans.m[1][1]=1;
base.m[0][0]=a,base.m[0][1]=b;
tree.Query(l,r,1,1,n,ans);
base=mul(base,ans);
printf("%lld %lld\n",base.m[0][0],base.m[0][1]);
}
}
//stop;
return 0;
} 
京公网安备 11010502036488号