zoukankan      html  css  js  c++  java
  • Codeforces 487E 圆方树 + 树链剖分

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = (int)2e5 + 7;
    const int inf = 0x3f3f3f3f;
    
    int n, m, q, w[N], pa[N], depth[N];
    vector<int> G[N], G2[N];
    multiset<int> mulset[N];
    
    int sz[N], son[N], top[N];
    int in[N], ot[N], idx;
    
    int bcc_cnt;
    int dfn[N], low[N], dfs_clock;
    int stk[N], tot;
    
    char op[10];
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    struct SegmentTree {
        int a[N << 2];
        void build(int l, int r, int rt) {
            a[rt] = inf;
            if(l == r) return;
            int mid = l + r >> 1;
            build(lson); build(rson);
        }
        void update(int p, int val, int l, int r, int rt) {
            if(l == r) {
                a[rt] = val;
                return;
            }
            int mid = l + r >> 1;
            if(p <= mid) update(p, val, lson);
            else update(p, val, rson);
            a[rt] = min(a[rt << 1], a[rt << 1 | 1]);
        }
        int query(int L, int R, int l, int r, int rt) {
            if(R < l || r < L || R < L) return inf;
            if(L <= l && r <= R) return a[rt];
            int mid = l + r >> 1;
            return min(query(L, R, lson), query(L, R, rson));
        }
    } Tree;
    
    void tarjan(int u, int fa) {
        dfn[u] = low[u] = ++dfs_clock;
        stk[++tot] = u;
        for(auto &v : G[u]) {
            if(v == fa) continue;
            if(!dfn[v]) {
                tarjan(v, u);
                low[u] = min(low[u], low[v]);
                if(low[v] >= dfn[u]) {
                    ++bcc_cnt;
                    while(1) {
                        int t = stk[tot--];
                        G2[t].push_back(bcc_cnt);
                        G2[bcc_cnt].push_back(t);
                        mulset[bcc_cnt].insert(w[t]);
                        if(t == v) break;
                    }
                    G2[u].push_back(bcc_cnt);
                    G2[bcc_cnt].push_back(u);
                    mulset[bcc_cnt].insert(w[u]);
                }
            }
            else if(dfn[v] < dfn[u]) {
                low[u] = min(low[u], dfn[v]);
            }
        }
    }
    
    void dfs(int u, int fa) {
        pa[u] = fa;
        sz[u] = 1;
        son[u] = 0;
        depth[u] = depth[fa] + 1;
        for(auto &v : G[u]) {
            if(v == fa) continue;
            dfs(v, u);
            sz[u] += sz[v];
            if(sz[son[u]] < sz[v]) {
                son[u] = v;
            }
        }
    }
    
    void dfs2(int u, int fa, int from) {
        top[u] = from;
        in[u] = ++idx;
        if(son[u]) dfs2(son[u], u, from);
        for(auto &v : G[u]) {
            if(v == fa || v == son[u]) continue;
            dfs2(v, u, v);
        }
        ot[u] = idx;
    }
    
    int solve(int u, int v) {
        int ans = inf;
        while(top[u] != top[v]) {
            if(depth[top[u]] < depth[top[v]]) swap(u, v);
            ans = min(ans, Tree.query(in[top[u]], in[u], 1, bcc_cnt, 1));
            u = pa[top[u]];
        }
        if(depth[u] < depth[v]) swap(u, v);
        ans = min(ans, Tree.query(in[v], in[u], 1, bcc_cnt,  1));
        if(v > n) ans = min(ans, w[pa[v]]);
        return ans;
    }
    
    int main() {
        scanf("%d%d%d", &n, &m, &q);
        bcc_cnt = n;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &w[i]);
        }
        for(int i = 1; i <= m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        tarjan(1, 0);
        for(int i = 1; i <= bcc_cnt; i++) {
            G[i] = G2[i];
        }
        dfs(1, 0);
        dfs2(1, 0, 1);
        Tree.build(1, bcc_cnt, 1);
        for(int i = 1; i <= n; i++) {
            Tree.update(in[i], w[i], 1, bcc_cnt, 1);
        }
        for(int i = n + 1; i <= bcc_cnt; i++) {
            mulset[i].insert(inf);
            if(pa[i]) mulset[i].erase(mulset[i].lower_bound(w[pa[i]]));
            Tree.update(in[i], *mulset[i].begin(), 1, bcc_cnt, 1);
        }
        while(q--) {
            int a, b;
            scanf("%s%d%d", op, &a, &b);
            if(*op == 'C') {
                if(pa[a]) mulset[pa[a]].erase(mulset[pa[a]].lower_bound(w[a]));
                w[a] = b;
                if(pa[a]) {
                    mulset[pa[a]].insert(w[a]);
                    Tree.update(in[pa[a]], *mulset[pa[a]].begin(), 1, bcc_cnt, 1);
                }
                Tree.update(in[a], w[a], 1, bcc_cnt, 1);
            }
            else {
                printf("%d
    ", solve(a, b));
            }
        }
        return 0;
    }
  • 相关阅读:
    php编译错误:jpeglib.h not found.
    php编译错误:Please reinstall the libcurl distribution
    php编译错误:Cannot find OpenSSL's <evp.h>
    php shmop windows 信号量锁
    vsftpd配置
    putty ssh 证书登录及问题
    mysql被收购 用mariadb
    centos 7 php7 yum源
    3dmax 欢迎页卡住
    用python进行服务器的监控
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11641333.html
Copyright © 2011-2022 走看看