• [bzoj2870]最长道路tree


    题目大意:给你一棵带点权的树,要你求出树上一条链,使得这条链的长度乘上这条链上点权最小值最大

    题解:点分,可以求出一个点向下每一条链上最小值以及路径长度,对于一个链的端点,假设到这部分子树的重心距离为$dep$,这条链上最小值为$min$,记录每一个最小值的最长链的长度,可以用树状数组维护最大值(这里是求后缀最大值,所以一次的复杂度还是$O(log_2n)$),更新答案就行了。

    卡点:1.写成了前缀求最大值

      2.离散化去重后长度未更改,导致用$lower\_bound$时出锅

    C++ Code:

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    
    namespace std {
        struct istream {
    #define M (1 << 26 | 3)
            char buf[M], *ch = buf - 1;
            int f;
            inline istream() {
    #ifndef ONLINE_JUDGE
                freopen("input.txt", "r", stdin);
    #endif
                fread(buf, 1, M, stdin);
            }
            inline istream& operator >> (int &x) {
                f = 1;
                while (isspace(*++ch));
                if (*ch == '-') f = -1, ch++;
                for (x = *ch & 15; isdigit(*++ch); ) x = x * 10 + (*ch & 15);
                return *this;
            }
    #undef M
        } cin;
        struct ostream {
    #define M (1 << 16 | 3)
            char buf[M], *ch = buf - 1;
            int w;
            inline ostream& operator << (int x) {
                if (!x) {
                    *++ch = '0';
                    return *this;
                }
                if (x < 0) *++ch = '-', x = -x;
                for (w = 1; w <= x; w *= 10);
                for (w /= 10; w; w /= 10) *++ch = (x / w) ^ 48, x %= w;
                return *this;
            }
            long long W;
            inline ostream& operator << (long long x) {
                if (!x) {
                    *++ch = '0';
                    return *this;
                }
                if (x < 0) *++ch = '-', x = -x;
                for (W = 1; W <= x; W *= 10);
                for (W /= 10; W; W /= 10) *++ch = (x / W) ^ 48, x %= W;
                return *this;
            }
            inline ostream& operator << (const char x) {*++ch = x; return *this;}
            inline ostream& operator << (const char *x) {
                while (*x) *this << *x++;
                return *this;
            }
            inline ~ostream() {
    #ifndef ONLINE_JUDGE
                freopen("output.txt", "w", stdout);
    #endif
                fwrite(buf, 1, ch - buf + 1, stdout);
            }
    #undef M
        } cout;
    }
    
    #define maxn 50010
    const int inf = 0x3f3f3f3f;
    inline void getmax(int &a, int b) {if (a < b) a = b;}
    inline void getmax(long long &a, int b) {if (a < b) a = b;}
    
    int head[maxn], cnt;
    struct Edge {
        int to, nxt;
    } e[maxn << 1];
    inline void addedge(int a, int b) {
        e[++cnt] = (Edge) {b, head[a]}; head[a] = cnt;
        e[++cnt] = (Edge) {a, head[b]}; head[b] = cnt;
    }
    
    bool vis[maxn];
    namespace Center_of_Gravity {
        int sz[maxn], nodenum;
        int MIN, root;
    #define n nodenum
        void __getroot(int u, int fa = 0) {
            sz[u] = 1;
            int MAX = 0;
            for (int i = head[u]; i; i = e[i].nxt) {
                int v = e[i].to;
                if (v != fa && !vis[v]) {
                    __getroot(v, u);
                    sz[u] += sz[v];
                    MAX = std::max(MAX, sz[v]);
                }
            }
            MAX = std::max(MAX, n - sz[u]);
            if (MAX < MIN) MIN = MAX, root = u;
        }
        int getroot(int u, int __nodenum = 0) {
            n = __nodenum ? __nodenum : sz[u];
            MIN = inf;
            __getroot(u);
            return root;
        }
    #undef n
    }
    using Center_of_Gravity::getroot;
    
    int n, tot;
    namespace BIT {
        int Tr[maxn], res;
    #define n tot
        inline void add(int p, const int num) {for (; p; p &= p - 1) getmax(Tr[p], num);}
        inline int ask(int p) {for (res = -inf; p <= n; p += p & -p) getmax(res, Tr[p]); return res;}
        inline void clear(int p) {for (; p; p &= p - 1) Tr[p] = -inf;}
    #undef n
    }
    
    int w[maxn], v[maxn];
    long long ans;
    
    int top;
    struct List {
        int tg, dep, min;
    } S[maxn];
    
    void calc() {
        for (int l = 1, r; l <= top; l = r + 1) {
            r = l;
            while (r < top && S[l].tg == S[r + 1].tg) r++;
            for (int i = l; i <= r; i++) {
                ans = std::max(ans, static_cast<long long> (BIT::ask(S[i].min) + S[i].dep + 1) * v[S[i].min]);
            }
            for (int i = l; i <= r; i++) BIT::add(S[i].min, S[i].dep);
        }
        for (int i = 1; i <= top; i++) BIT::clear(S[i].min);
    }
    
    void getlist(int u, int tg, int min, int dep = 1, int fa = 0) {
        min = std::min(min, w[u]);
        S[++top] = (List) {tg, dep, min};
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (v != fa && !vis[v]) getlist(v, tg, min, dep + 1, u);
        }
    }
    void solve(int u) {
        vis[u] = true; top = 0;
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (!vis[v]) getlist(v, v, w[u]);
        }
        calc();
        std::reverse(S + 1, S + top + 1);
        calc();
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (!vis[v]) solve(getroot(v));
        }
    }
    
    int main() {
        std::cin >> n;
        for (int i = 1; i <= n; i++) {
            std::cin >> w[i];
            getmax(ans, v[i] = w[i]);
        }
        tot = (std::sort(v + 1, v + n + 1), std::unique(v + 1, v + n + 1) - v - 1);
        for (int i = 1; i <= tot; i++) BIT::Tr[i] = -inf;
        for (int i = 1; i <= n; i++) {
            w[i] = std::lower_bound(v + 1, v + tot + 1, w[i]) - v;
        }
        for (int i = 1, a, b; i < n; i++) {
            std::cin >> a >> b;
            addedge(a, b);
        }
        solve(getroot(1, n));
        std::cout << ans << '
    ';
        return 0;
    }
    

      

  • 相关阅读:
    Java之路---Day09(继承)
    Java之路---Day08
    Java之路---Day07
    Java之路---Day06
    转载:js 创建对象、属性、方法
    Javascript类型检测
    jQuery 如何写插件
    js浮点数精度问题
    IE7.JS解决IE兼容性问题方法
    CSS 中文字体的英文名称 (simhei, simsun) 宋体 微软雅黑
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/10126676.html
Copyright © 2020-2023  润新知