• 【数据结构】线段树(字符串哈希)


    namespace SegmentTree {
    
    #define ls (o << 1)
    #define rs (o << 1 | 1)
    
        ll bse[3] = {13, 1331, 2333};
        ll mod[3] = {998244353, 1000000007, 1000000009};
        ll bsk[200005][3];
        ll st[200005 << 2][3];
    
        void Init(int n) {
            for(int t = 0; t < 3; ++t) {
                bsk[0][t] = 1;
                for(int i = 1; i <= n; ++i)
                    bsk[i][t] = (bsk[i - 1][t] * bse[t]) % mod[t];
            }
        }
    
        void PushUp(int o, int l, int r) {
            int m = (l + r) >> 1;
            for(int t = 0; t < 3; ++t)
                st[o][t] = (st[ls][t] * bsk[r - m][t] + st[rs][t]) % mod[t];
        }
    
        void Build(int o, int l, int r) {
            if(l == r) {
                for(int t = 0; t < 3; ++t)
                    st[o][t] = s[l];
            } else {
                int m = (l + r) >> 1;
                Build(ls, l, m);
                Build(rs, m + 1, r);
                PushUp(o, l, r);
            }
        }
    
        void Update(int o, int l, int r, int p, char v) {
            if(l == r) {
                for(int t = 0; t < 3; ++t)
                    st[o][t] = v;
            } else {
                int m = (l + r) >> 1;
                if(p <= m)
                    Update(ls, l, m, p, v);
                if(p >= m + 1)
                    Update(rs, m + 1, r, p, v);
                PushUp(o, l, r);
            }
        }
    
        ll Query(int o, int l, int r, int ql, int qr, int t) {
            if(ql <= l && r <= qr) {
                return st[o][t];
            } else {
                int m = (l + r) >> 1;
                ll res = 0;
                if(ql <= m)
                    res = Query(ls, l, m, ql, qr, t);
                if(qr >= m + 1)
                    res = (res * bsk[min(r, qr) - m][t] + Query(rs, m + 1, r, ql, qr, t)) % mod[t];
                return res;
            }
        }
    
    #undef ls
    #undef rs
    
    };
    

    区间赋值

    struct SegmentTree {
     
    #define ls (o << 1)
    #define rs (o << 1 | 1)
     
        ll bse[3] = {13, 1331, 2333};
        ll mod[3] = {998244353, 1000000007, 1000000009};
        ll bsk[100005][3];
        ll hslen[100005][10][3];
        ll st[100005 << 2][3];
        char lz[100005 << 2];
     
        void Init(int n) {
            for(int t = 0; t < 3; ++t) {
                bsk[0][t] = 1;
                for(int i = 1; i <= n; ++i)
                    bsk[i][t] = (bsk[i - 1][t] * bse[t]) % mod[t];
            }
            for(char c = '0'; c <= '9'; ++c) {
                for(int t = 0; t < 3; ++t) {
                    hslen[0][c - '0'][t] = 0;
                    for(int i = 1; i <= n; ++i)
                        hslen[i][c - '0'][t] = (hslen[i - 1][c - '0'][t] * bse[t] + c) % mod[t];
                }
            }
        }
     
        void PushUp(int o, int l, int r) {
            int m = (l + r) >> 1;
            for(int t = 0; t < 3; ++t)
                st[o][t] = (st[ls][t] * bsk[r - m][t] + st[rs][t]) % mod[t];
        }
     
        void PushDown(int o, int l, int r) {
            if(lz[o]) {
                int m = (l + r) >> 1;
                for(int t = 0; t < 3; ++t) {
                    st[ls][t] = hslen[m - l + 1][lz[o] - '0'][t];
                    st[rs][t] = hslen[r - m][lz[o] - '0'][t];
                }
                lz[ls] = lz[o];
                lz[rs] = lz[o];
                lz[o] = 0;
            }
        }
     
        void Build(int o, int l, int r) {
            lz[o] = 0;
            if(l == r) {
                for(int t = 0; t < 3; ++t)
                    st[o][t] = s[l];
            } else {
                int m = (l + r) >> 1;
                Build(ls, l, m);
                Build(rs, m + 1, r);
                PushUp(o, l, r);
            }
        }
     
        void Update(int o, int l, int r, int ql, int qr, char v) {
            if(ql <= l && r <= qr) {
                lz[o] = v;
                for(int t = 0; t < 3; ++t)
                    st[o][t] = hslen[(r - l + 1)][v - '0'][t];
            } else {
                PushDown(o, l, r);
                int m = (l + r) >> 1;
                if(ql <= m)
                    Update(ls, l, m, ql, qr, v);
                if(qr >= m + 1)
                    Update(rs, m + 1, r, ql, qr, v);
                PushUp(o, l, r);
            }
        }
     
        ll Query(int o, int l, int r, int ql, int qr, int t) {
            if(ql <= l && r <= qr) {
                return st[o][t];
            } else {
                PushDown(o, l, r);
                int m = (l + r) >> 1;
                ll res = 0;
                if(ql <= m)
                    res = Query(ls, l, m, ql, qr, t);
                if(qr >= m + 1)
                    res = (res * bsk[min(r, qr) - m][t] + Query(rs, m + 1, r, ql, qr, t)) % mod[t];
                return res;
            }
        }
     
    #undef ls
    #undef rs
     
    } st;
    
  • 相关阅读:
    PMP知识点总结(6月25日前不断更新)清辉PMP
    20220511内部群每日三题清辉PMP
    添加icon font图标
    element主题样式elementvariable.scss文件的内容
    安装nodesass失败
    Element实现树形控件单选
    idea开启services面板,查看多个服务运行情况
    Nacos启动异常:Nacos Server did not start because dumpservice bean construction failure : No DataSource set
    ElementSelect选择器结合树形控件升级版
    Element动态合并表格行
  • 原文地址:https://www.cnblogs.com/purinliang/p/14045044.html
Copyright © 2020-2023  润新知