參考的原博客:http://www.cnblogs.com/iRedBean/p/7398272.html
#include <bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int n,q;
const int maxn=1e5+9;
const long long mod=1e9+7;
struct matrix
{
long long m[3][3];
};
const matrix mp[2]= {{1,0,0,1,1,0,1,0,1},{1,1,0,0,1,0,0,1,1}};
matrix data[maxn<<2];
int f[maxn<<2];
char s[maxn];
matrix mul(matrix a,matrix b)
{
matrix tmp;
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
tmp.m[i][j]=0;
for(int k=0; k<3; k++)
tmp.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod;
tmp.m[i][j]%=mod;
}
}
return tmp;
}
void flip(matrix &x)
{
swap(x.m[0][0], x.m[0][1]);
swap(x.m[1][0], x.m[1][1]);
swap(x.m[2][0], x.m[2][1]);
swap(x.m[0][0], x.m[1][0]);
swap(x.m[0][1], x.m[1][1]);
}
void pushup(int rt)
{
data[rt]= mul(data[rt<<1],data[rt<<1|1]);
}
void pushdown(int rt)
{
if(f[rt])
{
flip(data[rt<<1]);
flip(data[rt<<1|1]);
f[rt<<1]^=f[rt];
f[rt<<1|1]^=f[rt];
f[rt]=0;
}
}
void build(int l,int r,int rt)
{
f[rt]=0;
if(l==r)
{
int t=s[l]-'0';
data[rt]=mp[t];
return;
}
int m=r+l>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
f[rt]=1-f[rt];
flip(data[rt]);
return;
}
int m=l+r>>1;
pushdown(rt);
if(L<=m) update(L,R,lson);
if(m<R) update(L,R,rson);
pushup(rt);
}
matrix query(int L,int R,int l,int r,int rt)
{
if(L==l&&r==R)
return data[rt];
int m=l+r>>1;
pushdown(rt);
if(R<=m) return query(L,R,lson);
else if(L>m) return query(L,R,rson);
else return mul(query(L,m,lson),query(m+1,R,rson));
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&q);
scanf("%s",s+1);
build(1,n,1);
while(q--)
{
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(op==1)
update(l,r,1,n,1);
else
{
matrix x=query(l,r,1,n,1);
printf("%I64d\n",(x.m[2][0]+x.m[2][1])%mod);
}
}
}
return 0;
}