Codeforces 718C Sasha and Array(线段树维护矩阵)

来源:互联网 发布:网站一键生成源码 编辑:程序博客网 时间:2024/06/05 15:13

线
GG

xf(x),af(x+a)
f(x+a)f(x)a
BA+CA=(B+C)A,
[f1,f0]
Ax1
线nlogn
lazynlognlognT
lazy
线
T


代码:

#include <map>#include <set>#include <stack>#include <queue>#include <cmath>#include <string>#include <vector>#include <cstdio>#include <cctype>#include <cstring>#include <sstream>#include <cstdlib>#include <iostream>#include <algorithm>#pragma comment(linker,"/STACK:102400000,102400000")using namespace std;#define   MAX           100010#define   MAXN          500005#define   maxnode       5#define   sigma_size    30#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   lrt           rt<<1#define   rrt           rt<<1|1#define   middle        int m=(r+l)>>1#define   LL            long long#define   ull           unsigned long long#define   mem(x,v)      memset(x,v,sizeof(x))#define   lowbit(x)     (x&-x)#define   pii           pair<int,int>#define   bits(a)       __builtin_popcount(a)#define   mk            make_pair#define   limit         10000//const int    prime = 999983;const int    INF   = 0x3f3f3f3f;const LL     INFF  = 0x3f3f;const double pi    = acos(-1.0);const double inf   = 1e18;const double eps   = 1e-6;const LL     mod   = 1e9+7;const ull    mx    = 133333331;/*****************************************************/inline void RI(int &x) {      char c;      while((c=getchar())<'0' || c>'9');      x=c-'0';      while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0'; }/*****************************************************/struct Matrix{    int n;    LL maze[maxnode][maxnode];    void init(int n){        this->n = n;        mem(maze,0);    }    Matrix operator + (Matrix &rhs){        Matrix m;        m.init(n);        for(int i=0;i<n;i++)            for(int j=0;j<n;j++){                m.maze[i][j] = maze[i][j] + rhs.maze[i][j];                if(m.maze[i][j]>=mod) m.maze[i][j]-=mod;            }                    //mod可以在二重循环的地方模        return m;///////    }    Matrix operator * (Matrix &rhs){        Matrix m;        m.init(n);        for(int i=0;i<n;i++)            for(int j=0;j<n;j++){                for(int k=0;k<n;k++){                    m.maze[i][j] += maze[i][k] * rhs.maze[k][j];                    //mod可以在二重循环的地方模                }                m.maze[i][j]%=mod;            }        return m;///////    }}A;Matrix qpow(Matrix a,LL n){    Matrix ans;    ans.init(a.n);    for(int i=0;i<ans.n;i++) ans.maze[i][i] = 1;    while(n){        if(n&1) ans = ans * a;        a = a*a;        n >>= 1;    }    return ans;}Matrix ma[MAX<<2];int a[MAX];Matrix col[MAX<<2];Matrix xx;void pushup(int rt){    ma[rt]=ma[lrt]+ma[rrt];}void pushdown(int rt){    if(col[rt].maze[0][0]!=1||col[rt].maze[0][1]!=0||col[rt].maze[1][0]!=0||col[rt].maze[1][1]!=1){        col[lrt]=col[lrt]*col[rt];        col[rrt]=col[rrt]*col[rt];        ma[lrt]=ma[lrt]*col[rt];        ma[rrt]=ma[rrt]*col[rt];        col[rt].maze[0][0]=1;col[rt].maze[0][1]=0;        col[rt].maze[1][0]=0;col[rt].maze[1][1]=1;    }}void build(int l,int r,int rt){    ma[rt].init(2);    col[rt].init(2);    col[rt].maze[0][0]=1;col[rt].maze[0][1]=0;    col[rt].maze[1][0]=0;col[rt].maze[1][1]=1;    if(l==r){        ma[rt]=qpow(A,a[l]-1);        return;    }    middle;    build(lson);    build(rson);    pushup(rt);}void update(int l,int r,int rt,int L,int R){    if(L<=l&&r<=R){        Matrix tmp;        col[rt]=col[rt]*xx;        ma[rt]=ma[rt]*xx;        return;    }    middle;    pushdown(rt);    if(L<=m) update(lson,L,R);    if(R>m) update(rson,L,R);    pushup(rt);}Matrix query(int l,int r,int rt,int L,int R){    if(L<=l&&r<=R) return ma[rt];    pushdown(rt);    Matrix ret;    ret.init(2);    middle;    if(L<=m){        Matrix tmp;        tmp.init(2);        tmp=query(lson,L,R);        ret=ret+tmp;    }    if(R>m){        Matrix tmp;        tmp.init(2);        tmp=query(rson,L,R);        ret=ret+tmp;    }    return ret;}int main(){    //freopen("in.txt","r",stdin);    int n,m;    while(cin>>n>>m){        for(int i=1;i<=n;i++) scanf("%d",&a[i]);        A.init(2);        A.maze[0][0]=1;A.maze[0][1]=1;        A.maze[1][0]=1;A.maze[1][1]=0;        build(1,n,1);        while(m--){            int op,l,r;            scanf("%d%d%d",&op,&l,&r);            if(op==1){                int x;                scanf("%d",&x);                xx.init(2);                xx=qpow(A,x);                update(1,n,1,l,r);            }            else{                Matrix ret=query(1,n,1,l,r);                printf("%I64d\n",ret.maze[0][0]);            }        }    }    return 0;}
0 0
原创粉丝点击