zoukankan      html  css  js  c++  java
  • HDU

    题目大意:给出n个点的权值。m条边,2种操作
    0 u num,将第u个点的权值改成num
    k u v,询问u到v这条路上第k大的权值点

    解题思路:该点的话直接该,找第k大的话直接暴力

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    #define N 80010
    #define M 160010
    
    struct Edge{
        int to, next, val;
    }E[M];
    
    int head[N], val[N], depth[M], ver[M], first[M], dis[M], dp[M][62], pre[N];
    int tot, n, m;
    bool vis[N];
    
    void AddEdge(int u, int v) {
        E[tot].to = v; E[tot].next = head[u]; E[tot].val = 1; head[u] = tot++;
        u = u ^ v; v = u ^ v; u = u ^ v;
        E[tot].to = v; E[tot].next = head[u]; E[tot].val = 1; head[u] = tot++;
    }
    
    void init() {
        for (int i = 1; i <= n; i++)
            scanf("%d", &val[i]);
        int u, v;
        memset(head, -1, sizeof(head));
        tot = 0;
    
        for (int i = 1; i < n; i++) {
            scanf("%d%d", &u, &v);
            AddEdge(u, v);
        }
    }
    
    void dfs(int u, int dep) {
        vis[u] = true; ver[++tot] = u; first[u] = tot; depth[tot] = dep;
        for (int i = head[u]; ~i; i = E[i].next) {
            int v = E[i].to;
            if (!vis[v]) {
                dis[v] = dis[u] + E[i].val;
                pre[v] = u;
                dfs(v, dep+1);
                ver[++tot] = u; depth[tot] = dep;
            }
        }
    } 
    
    void RMQ() {
        for (int i = 1; i <= tot; i++)
            dp[i][0] = i;
        int a, b;
        for (int j = 1; (1 << j) <= tot; j++)
            for (int i = 1; i + (1 << j) - 1 <= tot; i++) {
                a = dp[i][j - 1];
                b = dp[i + (1 << (j - 1))][j - 1];
                if (depth[a] < depth[b])
                    dp[i][j] = a;
                else
                    dp[i][j] = b;
            }
    }
    
    int Query(int x, int y) {
        int k = 0;
        while (1 << (k + 1) <= (y - x + 1)) k++;
        int a = dp[x][k];
        int b = dp[y - (1 << k) + 1][k];
        if (depth[a] < depth[b])
            return a;
        return b;
    }
    
    int LCA(int a, int b) {
        a = first[a];
        b = first[b];
        if (a > b) {
            a = a ^ b; b = a ^ b; a = a ^ b;
        }
        int c = Query(a, b);
        return ver[c];
    }
    
    int num[N], cnt;
    
    void path(int a, int lca) {
        int t = a;
        while (t != lca) {
            num[cnt++] = val[t];
            t = pre[t];
        }
    }
    
    bool cmp(const int a, const int b) {
        return a > b;
    }
    
    void find(int k, int a, int b) {
        int lca = LCA(a,b);
        if (dis[a] + dis[b] - 2 * dis[lca] + 1 < k) {
            printf("invalid request!
    ");
            return ;
        }
        else {
            cnt = 0;
            path(a, lca);
            path(b, lca);
            num[cnt++] = val[lca];
            sort(num, num + cnt, cmp);
            printf("%d
    ", num[k - 1]);
        }
    }
    
    void solve() {
        memset(vis, 0, sizeof(vis));
        tot = 0;
        dis[1] = 0;
        pre[1] = 1;
        dfs(1,1);
        RMQ();
    
        int k, a, b;
        while (m--) {
            scanf("%d%d%d", &k, &a, &b);
            if (!k) {
                val[a]=  b;
            }
            else {
                find(k, a, b);
            }
        }
    }
    
    int main() {
        while (scanf("%d%d", &n, &m) != EOF) {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    android 网络加载图片,对图片资源进行优化,并且实现内存双缓存 + 磁盘缓存
    Web前端框架与类库的思考
    android应用开发(十):widget的使用
    响应式WEB设计的9项基本原则
    谈一下关于CQRS架构如何实现高性能
    迪杰斯特拉算法——PAT 1003
    Android开发-SQLite数据库
    寻找水王(2)
    PAT-1003
    PAT-1002
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/7170159.html
Copyright © 2011-2022 走看看