CodeForces - 719E Sasha and Array 线段树 + 矩阵快速幂

来源:互联网 发布:淘宝如何卖电子书 编辑:程序博客网 时间:2024/06/04 18:43

传送门:CF 719 E

题解

区间更新
注意这里节点是矩阵, 所以初始化要是E
矩阵结合律 + Fibo
la表示lazy不过这里是矩阵, 所以初始是E, sum是区间的ans矩阵, lazy纯粹的标记


AC code:

/*adrui's submissionLanguage : C++Favorite : Dragon BallsLover : yyMotto : Choose & QuitStanding in the Hall of Fame*/#include<iostream>#include<cstring>using namespace std;#define mid ((l + r) >> 1)#define ls rt << 1, l, mid#define rs rt << 1 | 1, mid + 1, rtypedef long long LL;const int MOD = 1E9 + 7;const int maxn = 100000 + 5;int d[maxn];struct Matrix {//矩阵    LL v[2][2];    void clr() {        memset(v, 0, sizeof(v));    }    void E() {//单位矩阵        clr();        for (int i = 0; i < 2; ++i) v[i][i] = 1;    }    void debug() {        for (int i = 0; i < 2; ++i)            for (int j = 0; j < 2; ++j)                cout << v[i][j] << (j == 1 ? "\n" : " ");    }    Matrix operator * (Matrix b) {        Matrix res;        res.clr();        for (int i = 0; i < 2; ++i)            for (int j = 0; j < 2; ++j)                for (int k = 0; k < 2; ++k)                    res.v[i][j] = (res.v[i][j] + v[i][k] * b.v[k][j]) % MOD;        return res;    }    Matrix operator + (Matrix b) {        Matrix res;        //res.clr();        for (int i = 0; i < 2; ++i)            for (int j = 0; j < 2; ++j)                res.v[i][j] = (v[i][j] + b.v[i][j]) % MOD;        return res;    }    Matrix operator ^ (int b) {        Matrix res, a;        res.E();        memcpy(a.v, v, sizeof(v));        while (b) {            if (b & 1) res = res * a;            a = a * a;            b >>= 1;        }        return res;    }}mat, tmp;struct node {    int lazy;    Matrix sum, la;}a[maxn << 2];void pushUp(int rt) {    a[rt].sum = a[rt << 1].sum + a[rt << 1 | 1].sum;}void build(int rt, int l, int r) {    a[rt].la.E();//E    a[rt].lazy = 0;    if (l == r) {        cin >> d[l];        a[rt].sum = mat ^ d[l];        return;    }    build(ls);    build(rs);    pushUp(rt);}void down(int s, int f) {    a[s].lazy = a[f].lazy;    a[s].la = a[s].la * a[f].la;    a[s].sum = a[s].sum * a[f].la;}void pushDown(int rt) {    if (a[rt].lazy) {        down(rt << 1, rt);        down(rt << 1 | 1, rt);        a[rt].lazy = 0;        a[rt].la.E();//E    }}void update(int rt, int l, int r, int L, int R) {    if (L <= l && R >= r) {        a[rt].sum = a[rt].sum * tmp;        a[rt].la = a[rt].la * tmp;        a[rt].lazy = 1;        return;    }    pushDown(rt);    if (L <= mid) update(ls, L, R);    if (R > mid) update(rs, L, R);    pushUp(rt);}LL query(int rt, int l, int r, int L, int R) {    if (L <= l && R >= r)   return a[rt].sum.v[0][1];    pushDown(rt);    LL res = 0;    if (L <= mid) res += query(ls, L, R);    if (R > mid)    res += query(rs, L, R);    return res;}int main() {#ifndef ONLINE_JUDGE    freopen("in.txt", "r", stdin);#endif //    cin.tie(0);    cin.sync_with_stdio(false);    mat.clr();    mat.v[0][1] = mat.v[1][0] = mat.v[1][1] = 1;    //Fibonacci底数矩阵    int n, m, op, l, r, x;    while (cin >> n >> m) {        build(1, 1, n);        while (m--) {            cin >> op >> l >> r;            if (op == 1) {                cin >> x;                tmp = mat ^ x;                update(1, 1, n, l, r);            }            else {                LL ans = query(1, 1, n, l, r);                cout << ans % MOD << endl;            }        }    }    return 0;}
1 0
原创粉丝点击