• THUSC 2017 大魔*


    一个序列,每个物品有三个权值 $A,B,C$

    要求维护:

    1.区间 $A_i+=B_i$

    2.区间 $B_i+=C_i$

    3.区间 $C_i+=A_i$

    4.区间 $A_i+=v$

    5.区间 $B_i imes = v$

    6.区间 $C_i = v$

    7.询问区间 $A,B,C$ 各自的和

    线段树,每个点维护 $A,B,C,区间长度$

    每次修改相当于区间乘一个转移矩阵

    时间复杂度 $O(16nlogn)$

    垫底

    #include <bits/stdc++.h>
    #define LL long long
    using namespace std;
    #define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
    #define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
    inline int read() {
        int x = 0, f = 1; char ch = getchar();
        for (; !isdigit(ch); ch = getchar())if (ch == '-')f = -f;
        for (; isdigit(ch); ch = getchar()) x = 10 * x + ch - '0';
        return x * f;
    }
    const int mod = 998244353, maxn = 2.5e5 + 10;
    #define ls (x << 1)
    #define rs ((x << 1) | 1)
    int n, q, A[maxn], B[maxn], C[maxn];
    struct Matrix {
        int a[4][4];
        Matrix() {memset(a, 0, sizeof(a));}
        Matrix operator * (const Matrix &b) const {
            Matrix c;
            rep(i, 0, 3) rep(j, 0, 3) rep(k, 0, 3)
                (c.a[i][j] += (1LL * a[i][k] * b.a[k][j] % mod)) %= mod;
            return c;
        }
        Matrix operator + (const Matrix &b) const {
            Matrix c;
            rep(i, 0, 3) rep(j, 0, 3) c.a[i][j] = (a[i][j] + b.a[i][j]) % mod;
            return c;
        }
    }tag[maxn << 2];
    int seg[maxn << 2][4];
    void mul(int *f, Matrix gg) {
        int tmp[4] = {0, 0, 0, 0};
        rep(i, 0, 3) rep(j, 0, 3) (tmp[j] += (1LL * f[i] * gg.a[i][j] % mod)) %= mod;
        rep(i, 0, 3) f[i] = tmp[i];
    }
    inline int clear(Matrix x) {
        if (!(x.a[0][0] == 1 && x.a[1][1] == 1 && x.a[2][2] == 1 && x.a[3][3] == 1))return false;
        if (x.a[0][1] || x.a[0][2] || x.a[0][3] || x.a[1][0] || x.a[1][2] || x.a[1][3])return false;
        if (x.a[2][0] || x.a[2][1] || x.a[2][3] || x.a[3][0] || x.a[3][1] || x.a[3][2]) return false;
        return true;
    }
    inline void pushup(int x) {
        rep(i, 0, 3) seg[x][i] = (seg[ls][i] + seg[rs][i]) % mod;
    }
    inline void pushdown(int x) {
        if(clear(tag[x])) return;
        tag[ls] = tag[ls] * tag[x], tag[rs] = tag[rs] * tag[x];
        mul(seg[ls], tag[x]), mul(seg[rs], tag[x]);
        rep(i, 0, 3) rep(j, 0, 3) tag[x].a[i][j] = (i == j);
    }
    inline void build(int x, int l, int r) {
        if(l == r) {
            seg[x][0] = A[l]; seg[x][1] = B[l]; seg[x][2] = C[l]; seg[x][3] = 1;
            return;
        }
        int mid = (l + r) >> 1;
        build(ls, l, mid); build(rs, mid + 1, r);
        pushup(x);
    }
    Matrix cur; int res[4];
    inline void update(int x, int l, int r, int L, int R) {
        if(L <= l && r <= R) {
            mul(seg[x], cur);
            tag[x] = tag[x] * cur;
            return;
        }
        pushdown(x);
        int mid = (l + r) >> 1;
        if(L <= mid) update(ls, l, mid, L, R);
        if(R > mid) update(rs, mid + 1, r, L, R);
        pushup(x);
    }
    inline void query(int x, int l, int r, int L, int R) {
        if(L <= l && r <= R) {
            rep(i, 0, 3) (res[i] += seg[x][i]) %= mod;
            return;
        }
        pushdown(x);
        int mid = (l + r) >> 1;
        if(L <= mid) query(ls, l, mid, L, R);
        if(R > mid) query(rs, mid + 1, r, L, R);
    }
    int main() {
        n = read();
        rep(i, 1, (n<<2)) rep(j, 0, 3) rep(k, 0, 3) tag[i].a[j][k] = (j == k);
        rep(i, 1, n) A[i] = read(), B[i] = read(), C[i] = read();
        build(1, 1, n);
        q = read();
        while(q--) {
            int opt = read(), l = read(), r = read();
            rep(i, 0, 3) rep(j, 0, 3) cur.a[i][j] = (i == j);
            if(opt == 1) cur.a[1][0]++;
            else if(opt == 2) cur.a[2][1]++;
            else if(opt == 3) cur.a[0][2]++;
            else if(opt == 4) (cur.a[3][0] += read()) %= mod;
            else if(opt == 5) cur.a[1][1] = read();
            else if(opt == 6) cur.a[2][2] = 0, cur.a[3][2] = read();
            if(opt != 7) update(1, 1, n, l, r);
            if(opt == 7) {
                rep(i, 0, 3) res[i] = 0;
                query(1, 1, n, l, r);
                printf("%d %d %d
    ", res[0], res[1], res[2]);
                continue;
            }
        }
    }
    View Code
  • 相关阅读:
    Linux | Ubuntu 生成二维码实例
    Ubuntu 添加wine安装程序的快捷方式
    mysql 中文 排序
    Received disconnect from **.**).***.*** port 22:2: Too many authentication failures 解决办法
    php 数组与URL相互转换
    ssh `快捷键` 快速链接服务器
    使用ssh生成密钥并保存在不同的文件(ubuntu)
    H5移动端调试 weinre
    简单的 图片下载 php
    linux 系统生成二维码
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/10491587.html
Copyright © 2020-2023  润新知