zoukankan      html  css  js  c++  java
  • ACM Tax

    题目:http://codeforces.com/gym/101161

    题解:树上一条链的第k大,在DFS时Update,每颗线段树维护的是:树的根到这个节点的一条链,然后这多颗线段树组织成了主席树。对于询问( u , v ),直接处理u,v,Lca(u,v)三条链(根到这个节点的简单路径称为链),因为线段树维护的就是链,所以主席树直接查询就行了,和区间第k大一样的道理。我之所以一直说的是线段树,因为我认为主席树是多颗线段树的组织方式而已,重点依然在线段树。此题每颗线段树维护的是一条链!!!

    感受:成块的代码(比如LCA)一定要保证正确性啊,要不然好难调啊,orzzzzzzzz

    #pragma warning(disable:4996)
    #include<queue>
    #include<map>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define ll long long 
    #define mem(arr,in) memset(arr,in,sizeof(arr))
    using namespace std;
    
    const int maxn = 50005;
    
    int kase, n, q, tot, cnt, Max;
    int root[maxn], pa[maxn][20], dp[maxn], head[maxn];
    
    struct node { int to, va, next; } e[maxn * 2];
    struct code { int l, r, sum; } T[maxn * 20];
    
    void Inite() {
        Max = tot = cnt = 0;
        mem(dp, 0);
        mem(pa, -1);
        mem(head, -1);
    }
    
    void addedge(int u, int v, int w) {
        e[tot].to = v;
        e[tot].va = w;
        e[tot].next = head[u];
        head[u] = tot++;
    }
    
    void Update(int l, int r, int &rt, int pre, int p) {
        T[++cnt] = T[pre], T[cnt].sum++, rt = cnt;
        if (l == r) return;
        int mid = (l + r) >> 1;
        if (mid >= p) Update(l, mid, T[rt].l, T[pre].l, p);
        else Update(mid + 1, r, T[rt].r, T[pre].r, p);
    }
    
    int Query(int l, int r, int x, int y, int z, int k) {
        if (l == r) return l;
        int mid = (l + r) >> 1;
        int sum = T[T[x].l].sum + T[T[y].l].sum - 2 * T[T[z].l].sum;
        if (sum >= k) return Query(l, mid, T[x].l, T[y].l, T[z].l, k);
        else return Query(mid + 1, r, T[x].r, T[y].r, T[z].r, k - sum);
    }
    
    void DFS(int u, int p,int deep) {
        pa[u][0] = p;
        dp[u] = deep;
        for (int i = head[u]; i != -1; i = e[i].next) {
            int v = e[i].to;
            if (v != p) {
                Update(1, Max, root[v], root[u], e[i].va);
                DFS(v, u, deep + 1);
            }
        }
    }
    
    void Getpa() {
        DFS(1, -1, 0);
        for (int i = 1; (1 << i) <= n; i++) {
            for (int j = 1; j <= n; j++) {
                if (pa[j][i - 1] > 0) pa[j][i] = pa[pa[j][i - 1]][i - 1];
            }
        }
    }
    
    int Lca(int u, int v) {
        if (dp[u] > dp[v]) swap(u, v);
        for (int i = 0; i <= 19; i++) if ((dp[v] - dp[u]) >> i & 1) v = pa[v][i];        //不要跳过头了
        if (u == v) return u;
        for (int i = 19; i >= 0; i--) if (pa[u][i] != pa[v][i]) {
            u = pa[u][i];
            v = pa[v][i];
        }
        return pa[u][0];
    }
    
    int main()
    {
        scanf("%d", &kase);
        while (kase--) {
            scanf("%d", &n);
            Inite();
            for (int i = 2; i <= n; i++) {
                int u, v, w;
                scanf("%d%d%d", &u, &v, &w);
                addedge(u, v, w);
                addedge(v, u, w);
                Max = max(Max, w);
            }
    
            Getpa();
    
            scanf("%d", &q);
            for (int i = 1; i <= q; i++) {
                int u, v;
                scanf("%d%d", &u, &v);
    
                int x = Lca(u, v);
                int p = dp[u] + dp[v] - 2 * dp[x];          //判断这条路径上有几条边
    
                if (p % 2) {
                    double ans = (double)Query(1, Max, root[u], root[v], root[x], p / 2 + 1);
                    printf("%.1lf
    ", ans);
                }
                else {
                    double ans = (double)Query(1, Max, root[u], root[v], root[x], p / 2) + (double)Query(1, Max, root[u], root[v], root[x], p / 2 + 1);
                    printf("%.1lf
    ", ans / 2);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    Mysql Bypass小结
    SQLite手工注入方法小结
    bodgeit测试平台
    Sqlite注入测试
    ASP代码审计学习笔记 -3.上传漏洞
    centos7环境下apache2.2.34的编译安装
    centos7.6环境下编译安装tengine-2.2.2的编译安装
    centos7.6编译安装php7.2.11及redis/memcached/rabbitmq/openssl/curl等常见扩展
    Windows2016的 IIS中配置PHP7运行环境
    服务器资源迁移到aliyun对象存储及oss的权限管理配置
  • 原文地址:https://www.cnblogs.com/zgglj-com/p/9060499.html
Copyright © 2011-2022 走看看