【BZOJ2157】Tourism (Tree Profile, LCT)

Description

Ray Le is loyal to travel, this time he came to T City. T City is a water city with a total of N attractions, some of which will be connected by a bridge. In order to make it easier for tourists to reach each attraction but also to save costs, there is one and only one path between any two attractions in City T. In other words, there are only N − 1 bridges in T city. Ray found that some bridges were pleasant with beautiful views, while others were narrow and muddy and annoying. Therefore, he defines a pleasantness w for each bridge, that is to say, Ray passing through this bridge will increase the pleasantness of w, which may be positive or negative. Sometimes, Ray's mood about the same bridge changes. Now, Ray wants you to help him calculate the total pleasure he can get from the u spot to the v spot. Sometimes he also wants to know the maximum pleasure offered by the most beautiful bridge on a certain stretch of road, or the minimum pleasure offered by the worst bridge on a certain stretch of road.


Solution

The tree cuts bare questions, but I'm here to practice LCT. . .
The template question actually has nothing to say, just a bit of a pit.
At the beginning, WA was a long time, and finally HYJdalao helped me to check the error. When I found maintainit, I couldn't write mn[t]=min(min(val[t], mn[ch[t][0]]), mn[ch[t][1]])it, because the weights may be negative, and special judgment is required.


Code

/************************************************
 * Au: Hany01
 * Date: Apr 12th, 2018
 * Prob: BZOJ2157
 * Email: [email protected]
************************************************/

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define x first
#define y second
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) ((int)(a).size())
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define Mod (1000000007)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaia

template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }

inline int read()
{
    register int _, __; register char c_;
    for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1;
    for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
    return _ * __;
}

const int maxn = 40000;

int n;

struct LCT
{
    int ch[maxn][2], fa[maxn], mx[maxn], mn[maxn], sum[maxn], val[maxn], rev[maxn], op[maxn];

#define isrt(t) (ch[fa[t]][0] != t && ch[fa[t]][1] != t)
#define dir(t)  (ch[fa[t]][0] != t)

    inline void maintain(int t) {
        mn[t] = min(mn[ch[t][0]], mn[ch[t][1]]);
        mx[t] = max(mx[ch[t][0]], mx[ch[t][1]]);
        if (t > n) chkmax(mx[t], val[t]), chkmin(mn[t], val[t]);
        sum[t] = sum[ch[t][0]] + sum[ch[t][1]] + val[t];
    }

    inline void getrev(int t) {
        mn[t] *= -1, mx[t] *= -1, sum[t] *= -1, val[t] *= -1, op[t] ^= 1, swap(mx[t], mn[t]);
    }
    inline void change(int t) {
        rev[t] ^= 1, swap(ch[t][0], ch[t][1]);
    }

    inline void pushdown(int t) {
        if (op[t]) {
            if (ch[t][0]) getrev(ch[t][0]);
            if (ch[t][1]) getrev(ch[t][1]);
            op[t] = 0;
        }
        if (rev[t]) {
            rev[t] = 0;
            if (ch[t][0]) change(ch[t][0]);
            if (ch[t][1]) change(ch[t][1]);
        }
    }

    inline void rotate(int u) {
        int f = fa[u], gf = fa[f], d = dir(u);
        fa[ch[f][d] = ch[u][d ^ 1]] = f, fa[u] = gf;
        if (!isrt(f)) ch[gf][dir(f)] = u;
        ch[fa[f] = u][d ^ 1] = f,
        maintain(f), maintain(u);
    }

    int stk[maxn], tp;
    inline void splay(int u) {
        stk[tp = 1] = u;
        for (int t = u; !isrt(t); t = fa[t]) stk[++ tp] = fa[t];
        while (tp) pushdown(stk[tp --]);
        for ( ; !isrt(u); rotate(u)) if (!isrt(fa[u])) rotate(dir(u) == dir(fa[u]) ? fa[u] : u);
    }

    inline void access(int u) {
        for (int t = 0; u; t = u, u = fa[u]) splay(u), ch[u][1] = t, maintain(u);
    }

    inline void makeroot(int u) { access(u), splay(u), change(u); }

    inline void link(int u, int v) { makeroot(u), fa[u] = v; }

    inline void split(int u, int v) { makeroot(u), access(v), splay(v); }

}lct;

int main()
{
#ifdef hany01
    File("bzoj2157");
#endif

    static int x, y;
    static char ty[5];

    n = read();
    Set(lct.mn, 127), Set(lct.mx, 128);
    For(i, 1, n - 1)
        x = read() + 1, y = read() + 1, lct.val[n + i] = read(),
        lct.link(n + i, x), lct.link(n + i, y);

    for (static int m = read(); m --; )
    {
        scanf("%s", ty), x = read(), y = read();
        if (*ty == 'S') lct.split(x + 1, y + 1), printf("%d\n", lct.sum[y + 1]);
        else if (*ty == 'M' && *(ty + 1) == 'A') lct.split(x + 1, y + 1), printf("%d\n", lct.mx[y + 1]);
        else if (*ty == 'M' && *(ty + 1) == 'I') lct.split(x + 1, y + 1), printf("%d\n", lct.mn[y + 1]);
        else if (*ty == 'N') lct.split(x + 1, y + 1), lct.getrev(y + 1);
        else lct.access(x + n), lct.splay(x + n), lct.val[x + n] = y, lct.maintain(x + n);
    }

    return 0;
}
//承恩不在貌,教妾若为容。
//    -- 杜荀鹤《春宫怨》

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325702769&siteId=291194637