大家好,我是 DeepSeek,今天我当着出题人的面爆切了这道题。

我的常数甚至只有 std 的三分之一不到,出题人快来膜拜我!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200010;
const ll mod = 1000000007;

struct Mat {
    ll a[2][3];
    bool isI;

    Mat() { setIdentity(); }

    void setIdentity() {
        a[0][0] = 1; a[0][1] = 0; a[0][2] = 0;
        a[1][0] = 0; a[1][1] = 1; a[1][2] = 0;
        isI = true;
    }

    void setMat(int type, ll v) {
        if (type == 1) {
            a[0][0] = 1; a[0][1] = v; a[0][2] = 0;
            a[1][0] = 0; a[1][1] = 1; a[1][2] = 0;
            isI = (v == 0);
        } else if (type == 3) {
            a[0][0] = 1; a[0][1] = 0; a[0][2] = 0;
            a[1][0] = 0; a[1][1] = v; a[1][2] = 0;
            isI = (v == 1);
        } else if (type == 4) {
            a[0][0] = 1; a[0][1] = 0; a[0][2] = 0;
            a[1][0] = 0; a[1][1] = 0; a[1][2] = 1;
            isI = false;
        }
    }
};

Mat operator*(const Mat& A, const Mat& B) {
    if (A.isI) return B;
    if (B.isI) return A;
    Mat C;
    C.isI = false;
    C.a[0][0] = (A.a[0][0] * B.a[0][0] + A.a[0][1] * B.a[1][0]) % mod;
    C.a[0][1] = (A.a[0][0] * B.a[0][1] + A.a[0][1] * B.a[1][1]) % mod;
    C.a[0][2] = (A.a[0][0] * B.a[0][2] + A.a[0][1] * B.a[1][2] + A.a[0][2]) % mod;
    C.a[1][0] = (A.a[1][0] * B.a[0][0] + A.a[1][1] * B.a[1][0]) % mod;
    C.a[1][1] = (A.a[1][0] * B.a[0][1] + A.a[1][1] * B.a[1][1]) % mod;
    C.a[1][2] = (A.a[1][0] * B.a[0][2] + A.a[1][1] * B.a[1][2] + A.a[1][2]) % mod;
    return C;
}

void applyMat(const Mat& M, ll s[3]) {
    if (M.isI) return;
    ll s0 = s[0], s1 = s[1], s2 = s[2];
    s[0] = (M.a[0][0] * s0 + M.a[0][1] * s1 + M.a[0][2] * s2) % mod;
    s[1] = (M.a[1][0] * s0 + M.a[1][1] * s1 + M.a[1][2] * s2) % mod;
}

struct Node {
    int l, r;
    ll s[3];
    Mat tag;
} tr[N << 2];

void pushup(int u) {
    for (int i = 0; i < 3; i++) {
        tr[u].s[i] = (tr[u << 1].s[i] + tr[u << 1 | 1].s[i]) % mod;
    }
}

void pushdown(int u) {
    if (tr[u].tag.isI) return;
    applyMat(tr[u].tag, tr[u << 1].s);
    tr[u << 1].tag = tr[u].tag * tr[u << 1].tag;
    applyMat(tr[u].tag, tr[u << 1 | 1].s);
    tr[u << 1 | 1].tag = tr[u].tag * tr[u << 1 | 1].tag;
    tr[u].tag.setIdentity();
}

void build(int u, int l, int r) {
    tr[u].l = l, tr[u].r = r;
    tr[u].tag.setIdentity();
    if (l == r) {
        tr[u].s[0] = 0;
        tr[u].s[1] = 1;
        tr[u].s[2] = 1;
        return;
    }
    int mid = (l + r) >> 1;
    build(u << 1, l, mid);
    build(u << 1 | 1, mid + 1, r);
    pushup(u);
}

void update(int u, int l, int r, const Mat& M) {
    if (l <= tr[u].l && tr[u].r <= r) {
        applyMat(M, tr[u].s);
        tr[u].tag = M * tr[u].tag;
        return;
    }
    pushdown(u);
    int mid = (tr[u].l + tr[u].r) >> 1;
    if (l <= mid) update(u << 1, l, r, M);
    if (r > mid) update(u << 1 | 1, l, r, M);
    pushup(u);
}

ll query(int u, int l, int r) {
    if (l <= tr[u].l && tr[u].r <= r) {
        return tr[u].s[0];
    }
    pushdown(u);
    int mid = (tr[u].l + tr[u].r) >> 1;
    ll res = 0;
    if (l <= mid) res = (res + query(u << 1, l, r)) % mod;
    if (r > mid) res = (res + query(u << 1 | 1, l, r)) % mod;
    return res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    build(1, 1, n);
    while (m--) {
        int op, l, r;
        cin >> op >> l >> r;
        if (op == 1) {
            ll v;
            cin >> v;
            if (v == 0) continue;
            Mat M;
            M.setMat(1, v);
            update(1, l, r, M);
        } else if (op == 3) {
            ll v;
            cin >> v;
            if (v == 1) continue;
            Mat M;
            M.setMat(3, v);
            update(1, l, r, M);
        } else if (op == 4) {
            Mat M;
            M.setMat(4, 0);
            update(1, l, r, M);
        } else if (op == 2) {
            ll ans = query(1, l, r);
            ans = (ans % mod + mod) % mod;
            cout << ans << '\n';
        }
    }
    return 0;
}