hdu 6155 线段树加矩阵快速幂

来源:互联网 发布:linux删除文件夹内容 编辑:程序博客网 时间:2024/05/14 04:00

http://acm.hdu.edu.cn/showproblem.php?pid=6155

第一次做矩阵快速幂套线段树的题,感觉好神奇


#include<bits/stdc++.h>using namespace std;const int maxn=1e5+5,mo=1e9+7;struct NODE{    long long a[3][3];}t1,t2,be;NODE mult(NODE a,NODE b){    NODE c;    memset(c.a,0,sizeof(c.a));    for(int i=0;i<3;i++)    {        for(int j=0;j<3;j++)        {            for(int k=0;k<3;k++)            {                c.a[i][j]+=a.a[i][k]*b.a[k][j];                if(c.a[i][j]>=mo)                    c.a[i][j]%=mo;            }        }    }    return c;}NODE seg[4*maxn];bool lazy[4*maxn];int num[maxn];void pushup(int node){    seg[node]=mult(seg[node<<1],seg[node<<1|1]);}void change(NODE &a){    for(int i=0;i<3;i++)        swap(a.a[i][0],a.a[i][1]);    for(int i=0;i<3;i++)        swap(a.a[0][i],a.a[1][i]);}void pushdown(int node){    if(lazy[node])    {        lazy[node<<1]=!lazy[node<<1];        lazy[node<<1|1]=!lazy[node<<1|1];        change(seg[node<<1]);        change(seg[node<<1|1]);        lazy[node]=0;    }}void build(int l,int r,int node){    lazy[node]=0;    if(l==r)    {        seg[node]=num[l]?t2:t1;        return ;    }    int m=(l+r)>>1;    build(l,m,node<<1);    build(m+1,r,node<<1|1);    pushup(node);    return ;}void update(int le,int ri,int l,int r,int node){    if(l>=le&&r<=ri)    {        lazy[node]=!lazy[node];        change(seg[node]);        return ;    }    pushdown(node);    int m=(l+r)>>1;    if(m>=le)    update(le,ri,l,m,node<<1);    if(m<ri)    update(le,ri,m+1,r,node<<1|1);    pushup(node);    return ;}NODE query(int le,int ri,int l,int r,int node){    if(l>=le&&r<=ri)    {        return seg[node];    }    pushdown(node);    NODE sum;    memset(sum.a,0,sizeof sum.a);    for(int i=0;i<3;i++)        sum.a[i][i]=1;    int m=(l+r)>>1;    if(m>=le)        sum=mult(sum,query(le,ri,l,m,node<<1));    if(m<ri)        sum=mult(sum,query(le,ri,m+1,r,node<<1|1));    return sum;}int ch[maxn];int main(){    t1.a[0][0]=t1.a[1][0]=t1.a[2][0]=t1.a[1][1]=t1.a[2][2]=1;    t2.a[0][0]=t2.a[0][1]=t2.a[1][1]=t2.a[2][1]=t2.a[2][2]=1;    be.a[0][2]=1;    int T,n,q,ty,l,r;    NODE ans;    cin>>T;    while(T--)    {        cin>>n>>q;        for(int i=1;i<=n;i++)            scanf("%1d",&num[i]);        build(1,n,1);        while(q--)        {            scanf("%d %d %d",&ty,&l,&r);            if(ty-1)            {                ans=mult(be,query(l,r,1,n,1));                printf("%lld\n",(ans.a[0][0]+ans.a[0][1])%mo);            }            else            {                update(l,r,1,n,1);            }        }    }    return 0;}


原创粉丝点击