• CF893F Subtree Minimum Query 主席树


    如果是求和就很好做了...

    不是求和也无伤大雅....

    一维太难限制条件了,考虑二维限制

    一维$dfs$序,一维$dep$序

    询问$(x, k)$对应着在$dfs$上查$[dfn[x], dfn[x] + sz[x] - 1]$,在$dep$序上查$[dep[x], dep[x] + k]$

    这样子,每个询问对应查询一段矩形内的最小值

    然而树套树是过不了的.....

    发现一个询问看似在$dep$序上对应了一段区间,实际上可以扩展到对应一段前缀

    这样子,只需要一个主席树就可以做到了

    复杂度$O(n log n)$

    #include <map>
    #include <queue>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    namespace remoon {
        #define ri register int
        #define tpr template <typename ra>
        #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
        #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)    
        #define gc getchar
        inline int read() {
            int p = 0, w = 1; char c = gc();
            while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); }
            while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc();
            return p * w;
        }
        int wr[50], rw;
        #define pc(iw) putchar(iw)
        tpr inline void write(ra o, char c = '
    ') {
            if(!o) pc('0');
            if(o < 0) o = -o, pc('-');
            while(o) wr[++ rw] = o % 10, o /= 10;
            while(rw) pc(wr[rw --] + '0');
            pc(c);
        }
        tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; }
        tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; } 
        tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, 1 : 0; }
        tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, 1 : 0; }
    }
    using namespace std;
    using namespace remoon;
    
    #define sid 300050
    #define oid 12050000
    
    int dfn[sid], sz[sid];
    int n, r, m, id, tim, cnp, mxd;
    int rt[sid], nxt[sid], node[sid], cap[sid];
    int fa[sid], q[sid], w[sid], dep[sid];
    int ls[oid], rs[oid], miv[oid];
    
    inline void addedge(int u, int v) {
        nxt[++ cnp] = cap[u]; cap[u] = cnp; node[cnp] = v;
    }
    
    #define cur node[i]
    inline void dfs(int o, int f) {
        fa[o] = f; dep[o] = dep[f] + 1;
        sz[o] = 1; dfn[o] = ++ tim;
        for(int i = cap[o]; i; i = nxt[i])
        if(cur != f) dfs(cur, o), sz[o] += sz[cur];
    }
    
    inline void insert(int &now, int pre, int l, int r, int p, int v) {
        now = ++ id;
        ls[now] = ls[pre]; rs[now] = rs[pre];
        miv[now] = min(miv[pre], v);
        if(l == r) return;
        int mid = (l + r) >> 1;
        if(p <= mid) insert(ls[now], ls[pre], l, mid, p, v);
        else insert(rs[now], rs[pre], mid + 1, r, p, v);
    }
    
    inline void build() {    
        int fr = 1, to = 0; 
        q[++ to] = r; miv[0] = 1e9;
        while(fr <= to) {
            int o = q[fr];
            for(ri i = cap[o]; i; i = nxt[i])
            if(cur != fa[o]) q[++ to] = cur;
            if(dep[o] != dep[q[fr - 1]]) 
            insert(rt[dep[o]], rt[dep[o] - 1], 1, n, dfn[o], w[o]);
            else insert(rt[dep[o]], rt[dep[o]], 1, n, dfn[o], w[o]);
            fr ++; cmax(mxd, dep[o]);
        }
    }
    
    inline int qry(int o, int l, int r, int ml, int mr) {
        if(ml > r || mr < l || !o) return 1e9;
        if(ml <= l && mr >= r) return miv[o];
        int mid = (l + r) >> 1;
        return min(qry(ls[o], l, mid, ml, mr), qry(rs[o], mid + 1, r, ml, mr));
    }
    
    int main() {
        n = read(); r = read();
        rep(i, 1, n) w[i] = read();
        rep(i, 2, n) {
            int u = read(), v = read();
            addedge(u, v); addedge(v, u);
        }
        dfs(r, 0); build();
        int lst = 0; m = read();
        rep(i, 1, m) {
            int x = (read() + lst) % n + 1;
            int k = (read() + lst) % n;
            write(lst = qry(rt[min(dep[x] + k, mxd)], 1, n, dfn[x], dfn[x] + sz[x] - 1));
        }
        return 0;
    }
  • 相关阅读:
    一本通1402 Vigen&#232;re密码
    一本通1166 求f(x,n)
    一本通1083 计算星期几
    一本通1157 哥德巴赫猜想
    一本通1156 求π的值
    SpringBoot多数据源:动态数据源
    cron 表达式
    自定义异常类
    CentOS7 常用命令集合
    想要学好Git,应该掌握哪些基础知识?
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9819614.html
Copyright © 2020-2023  润新知