zoukankan      html  css  js  c++  java
  • 【数据结构】线段树(字符串哈希)

    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;
    
  • 相关阅读:
    linux下通过命令行重启服务,查看id,更改tv密码
    windows渗透相关、hideadmin工具隐藏用户账号、添加隐藏用户
    windows服务隐藏 以及进程隐藏
    nat32 winh命令远程执行难点
    anydesk命令行使用
    html页面,能用鼠标滚轮滑动,但是不能触屏滑动
    Java 全局统一异常捕获
    git 常用操作
    vue v-for强制刷新
    flutter-TextField垂直居中
  • 原文地址:https://www.cnblogs.com/purinliang/p/14045044.html
Copyright © 2011-2022 走看看