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;
    }
  • 相关阅读:
    2.Android之按钮Button和编辑框EditText学习
    《DSP using MATLAB》Problem 3.8
    《DSP using MATLAB》Problem 3.7
    《DSP using MATLAB》Problem 3.6
    《DSP using MATLAB》Problem 3.5
    《DSP using MATLAB》Problem 3.4
    《DSP using MATLAB》Problem 3.3
    《DSP using MATLAB》Problem 3.2
    《DSP using MATLAB》Problem 3.1
    《DSP using MATLAB》Problem 2.20
  • 原文地址:https://www.cnblogs.com/handsomeJian/p/3947758.html
Copyright © 2011-2022 走看看