zoukankan      html  css  js  c++  java
  • poj 3237 Tree

        就是简单的树链剖分,但标记下传的时候一定要 ^1 而不能直接 = 1,我竟然WA在这么逗比的错误上不如一头撞死……

        上代码:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define N 1100000
    #define inf 0x7f7f7f7f
    using namespace std;
    
    struct sss
    {
        int minnum, maxnum;
        int push;
    }t[N*4];
    int n, nowplace, bianp[N];
    int p[N], next[N*2], v[N*2], c[N*2], bnum;
    int fa[N], son[N], siz[N], deep[N], top[N], w[N];
    
    void build_tree(int now, int l, int r)
    {
        t[now].minnum = inf; t[now].maxnum = -inf; t[now].push = 0;
        if (l == r) return;
        int mid = (l+r)/2;
        build_tree(now*2, l, mid); build_tree(now*2+1, mid+1, r);
    }
    
    void downdate(int now)
    {
        if (!t[now].push) return; t[now].push = 0;
        t[now*2].push ^= 1; t[now*2+1].push ^= 1;
        swap(t[now*2].maxnum, t[now*2].minnum);
        swap(t[now*2+1].maxnum, t[now*2+1].minnum);
        t[now*2].maxnum *= -1; t[now*2].minnum *= -1;
        t[now*2+1].maxnum *= -1; t[now*2+1].minnum *= -1;
    }
    
    void update(int now)
    {
        t[now].maxnum = max(t[now*2].maxnum, t[now*2+1].maxnum);
        t[now].minnum = min(t[now*2].minnum, t[now*2+1].minnum);
    }
    
    void addbian(int x, int y)
    {
        bnum++; next[bnum] = p[x]; p[x] = bnum; v[bnum] = y;
        bnum++; next[bnum] = p[y]; p[y] = bnum; v[bnum] = x;
    }
    
    void dfs_1(int now, int nowfa, int nowdeep)
    {
        int k = p[now]; fa[now] = nowfa; deep[now] = nowdeep;
        int maxson = 0; son[now] = 0; siz[now] = 1;
        while (k)
        {
            if (v[k] != nowfa)
            {
                bianp[(k+1)/2] = v[k];
                dfs_1(v[k], now, nowdeep+1);
                siz[now] += siz[v[k]];
                if (siz[v[k]] > maxson)
                {
                    maxson = siz[v[k]];
                    son[now] = v[k];
                }
            }
            k = next[k];
        }
    }
    
    void dfs_2(int now, int nowfa, int nowtop)
    {
        int k = p[now]; top[now] = nowtop; w[now] = ++nowplace;
        if (son[now]) dfs_2(son[now], now, nowtop);
        while (k)
        {
            if (v[k] != nowfa && v[k] != son[now])
                dfs_2(v[k], now, v[k]);
            k = next[k];
        }
    }
    
    int task(int now, int l, int r, int al, int ar)
    {
        if (al <= l && r <= ar)    return t[now].maxnum;
        int mid = (l+r)/2, ans = -inf;
        downdate(now);
        if (al <= mid) ans = task(now*2, l, mid, al, ar);
        if (ar > mid) ans = max(ans, task(now*2+1, mid+1, r, al, ar));
        update(now); return ans;
    }
    
    void tneg(int now, int l, int r, int tl, int tr)
    {
        if (tl <= l && r <= tr)
        {
            downdate(now);
            swap(t[now].maxnum, t[now].minnum);
            t[now].maxnum *= -1; t[now].minnum *= -1;
            t[now].push ^= 1; return;
        }
        int mid = (l+r)/2;
        downdate(now);
        if (tl <= mid) tneg(now*2, l, mid, tl, tr);
        if (tr > mid) tneg(now*2+1, mid+1, r, tl, tr);
        update(now); return;
    }
    
    void chan(int now, int l, int r, int cplace, int cnum)
    {
        if (l == r)
        {
            t[now].maxnum = t[now].minnum = cnum;
            return;
        }
        int mid = (l+r)/2;
        downdate(now);
        if (cplace <= mid) chan(now*2, l, mid, cplace, cnum);
        else chan(now*2+1, mid+1, r, cplace, cnum);
        update(now); return;
    }
    
    void neg(int u, int v)
    {
        int f1 = top[u], f2 = top[v];
        if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); }
        if (f1 == f2)
        {
            if (u == v) return;
            if (w[u] > w[v]) swap(u, v);
            tneg(1, 1, n, w[son[u]], w[v]);
            return;
        }
        tneg(1, 1, n, w[f1], w[u]); neg(fa[f1], v);
    }
    
    int find(int u, int v)
    {
        int f1 = top[u],f2 = top[v];
        if (deep[f1] < deep[f2]) { swap(f1, f2); swap(u, v); }
        if (f1 == f2)
        {
            if (u == v) return -inf;
            if (w[u] > w[v]) swap(u, v);
            return task(1, 1, n, w[son[u]], w[v]);
        }
        int ans = task(1, 1, n, w[f1], w[u]);
        return max(ans, find(fa[f1], v));
    }
    
    int main()
    {
        int T; scanf("%d", &T);
        while (T--)
        {
            scanf("%d", &n); memset(p, 0, sizeof(p));
            build_tree(1, 1, n); nowplace = 0; bnum = 0;
            for (int i = 1; i < n; ++i)
            {
                int x, y, z; scanf("%d%d%d", &x, &y, &z);
                addbian(x, y); c[i] = z;
            }
            dfs_1(1, 0, 1);
            dfs_2(1, 0, 1);
            for (int i = 1; i < n; ++i)
                chan(1, 1, n, w[bianp[i]], c[i]);
            char s[8];
            while (scanf("%s", s) != EOF)
            {
                if (s[0] == 'D') break;
                int x, y; scanf("%d%d", &x, &y);
                if (s[0] == 'Q') printf("%d
    ", find(x, y));
                else if (s[0] == 'C') chan(1, 1, n, w[bianp[x]], y);
                else if (s[0]=='N') neg(x, y);
            }
        }
        return 0;
    }
  • 相关阅读:
    并发编程(六)并发队列
    并发编程(五)原子类
    Java基础一篇过(九)面向对象之多态【向上转型与向下转型】
    ArrayList源码解析
    Redis5设计与源码分析读后感(四)压缩列表
    Redis5设计与源码分析读后感(三)跳跃表
    Python学习————CBV模型
    Python学习————Django
    Python学习————JS
    Python学习————SEO和SEC
  • 原文地址:https://www.cnblogs.com/handsomeJian/p/3947758.html
Copyright © 2011-2022 走看看