题意:
给出一个长度为n的01串s,两种操作:
1.反转区间[l,r],即把0变成1,把1变成0
2.询问区间[l,r]中不同的子序列个数
思路:
#include<bits/stdc++.h>
using namespace std;
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
typedef long long ll;
typedef pair<int,int>pii;
const ll INF=0x3f3f3f3f;
const ll mod=1e9+7;
const int maxn=1e5+6;
int T,n,q,lazy[maxn<<2];
char s[maxn];
struct node{
ll a[3][3];
node operator * (const node& x){
node t;
memset(t.a,0,sizeof(t.a));
for(int i=0;i<=2;i++)
for(int j=0;j<=2;j++)
for(int k=0;k<=2;k++)
t.a[i][j]=(t.a[i][j]+a[i][k]*x.a[k][j]%mod)%mod;
return t;
}
}e[maxn<<2];
node st[2]={{1,0,0,1,1,0,1,0,1},{1,1,0,0,1,0,0,1,1}};
void pushup(int rt){
e[rt]=e[rt<<1]*e[rt<<1|1];
}
void build(int rt,int l,int r){
lazy[rt]=0;
if(l==r){
e[rt]=st[s[l]-'0'];
return;
}
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void upnow(int rt){
swap(e[rt].a[0][0],e[rt].a[1][1]);
swap(e[rt].a[1][0],e[rt].a[0][1]);
swap(e[rt].a[2][0],e[rt].a[2][1]);
swap(e[rt].a[0][2],e[rt].a[1][2]);
}
void pushdown(int rt){
if(lazy[rt]){
upnow(rt<<1);
upnow(rt<<1|1);
lazy[rt<<1]^=1;
lazy[rt<<1|1]^=1;
lazy[rt]=0;
}
}
void update(int rt,int l,int r,int x,int y){
if(x<=l&&r<=y){
upnow(rt);
lazy[rt]^=1;
return;
}
int mid=(l+r)>>1;
pushdown(rt);
if(x<=mid)update(lson,x,y);
if(y>mid)update(rson,x,y);
pushup(rt);
}
node query(int rt,int l,int r,int x,int y){
if(x<=l&&r<=y)return e[rt];
int mid=(l+r)>>1;
pushdown(rt);
node res={1,0,0,0,1,0,0,0,1};
if(x<=mid)res=res*query(lson,x,y);
if(y>mid)res=res*query(rson,x,y);
return res;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%s",&n,&q,s+1);
build(1,1,n);
while(q--){
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==1){
update(1,1,n,x,y);
}
else {
node ans=query(1,1,n,x,y);
node h={0,0,1,0,0,0,0,0,0};
h=h*ans;
printf("%lld\n",(h.a[0][0]+h.a[0][1])%mod);
}
}
}
}