Hdu 6155 segment tree maintenance transition matrix

The difficulty of this problem is not on the line segment tree. In fact, as long as the problem of how to find how many different substrings of a 01 string is solved, it is basically a smooth ride. So my team GG because they don't count games. . . Later, I watched Sister Fork's problem solution and learned to count, so I finished writing xjb.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int maxn=105000;

struct mat{
    ll a[3][3];
    void init(int tag){
        memset(a, 0, sizeof(a));
        if(tag==0){
            a[0][0]=a[0][1]=a[0][2]=a[1][1]=a[2][2]=1;
        }
        else {
            a[0][0]=a[1][0]=a[1][1]=a[1][2]=a[2][2]=1;
        }
    }
    void rev(){
        swap(a[0][0], a[1][1]);
        swap(a[0][1], a[1][0]);
        swap(a[0][2], a[1][2]);
    }
};

mat operator*(const mat& a, const mat& b){
    mat ans;
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++){
            ans.a[i][j]=0;
            for(int k=0;k<3;k++){
                ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
            }
        }
    }
    return ans;
}

char s[maxn];
int n, m;

mat rec[maxn<<2];
int lz[maxn<<2];

void pushdown(int u){
    if(!lz[u])return ;
    rec[2*u].rev();
    lz[2*u]^=1;
    rec[2*u+1].rev();
    lz[2*u+1]^=1;
    lz[u]=0;
}

void pushup(int u){
    rec[u]=rec[2*u+1]*rec[2*u];
}

void build(int u, int l, int r){
    lz[u]=0;
    if(l==r){
        rec[u].init(s[l]-'0');
        return ;
    }
    int mid=(l+r)>>1;
    build(2*u, l, mid);
    build(2*u+1, mid+1, r);
    pushup(u);
}

void update(int u, int ql, int qr, int l, int r){
    if(ql>r||qr<l)return;
    if(ql<=l&&r<=qr){
        rec[u].rev();
        lz[u]^=1;
        return ;
    }
    int mid=(l+r)>>1;
    pushdown(u);
    update(2*u, ql, qr, l, mid);
    update(2*u+1, ql, qr, mid+1, r);
    pushup(u);
}

mat query(int u, int ql, int qr, int l, int r){
    if(ql<=l&&r<=qr){
        return rec[u];
    }
    int mid=(l+r)>>1;
    pushdown(u);
    mat ret;
    for(int i=0;i<3;i++){
        for(int j=0;j<3;j++)ret.a[i][j]=(i==j);
    }
    if(mid>=ql)ret=query(2*u, ql, qr, l, mid)*ret;
    if(mid+1<=qr)ret=query(2*u+1, ql, qr, mid+1, r)*ret;
    return ret;
}

int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d%d", &n, &m);
        scanf("%s", s+1);
        build(1, 1, n);
        for(int i=1;i<=m;i++){
            int tag, l, r;
            scanf("%d%d%d", &tag, &l, &r);
            if(tag==1){
                update(1, l, r, 1, n);
            }
            else {
                mat m=query(1, l, r, 1, n);
                printf("%lld\n", (m.a[0][2]+m.a[1][2])%mod);
            }
        }
    }
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325945996&siteId=291194637