zoukankan      html  css  js  c++  java
  • [BZOJ 3083] 遥远的国度

    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=3083

    [算法]

             树链剖分

             时间复杂度 : O(NlogN ^ 2)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 100010
    #define MAXLOG 20
    const int inf = 2e9;
    
    struct edge
    {
            int to , nxt;
    } e[MAXN << 1];
    
    int n , q , tot , timer , rt;
    int a[MAXN] , head[MAXN] , dfn[MAXN] , l[MAXN] , r[MAXN] , fa[MAXN] , loc[MAXN] , son[MAXN] , size[MAXN] , top[MAXN] , depth[MAXN];
    int up[MAXN][MAXLOG];
    
    struct Segment_Tree
    {
            struct Node
            {
                    int l , r;
                    int value , tag;
            } Tree[MAXN << 2];
            inline void update(int index)
            {
                    Tree[index].value = min(Tree[index << 1].value , Tree[index << 1 | 1].value);
            }
            inline void pushdown(int index)
            {
                    if (Tree[index].tag != -1)
                    {
                            Tree[index << 1].value = Tree[index << 1 | 1].value = Tree[index].tag;
                            Tree[index << 1].tag = Tree[index << 1 | 1].tag = Tree[index].tag;
                            Tree[index].tag = -1;
                    }
            }
            inline void build(int index , int l , int r)
            {
                    Tree[index].l = l;
                    Tree[index].r = r;
                    Tree[index].tag = -1;
                    if (l == r)
                    {
                            Tree[index].value = a[loc[l]];
                            return;
                    }
                    int mid = (l + r) >> 1;
                    build(index << 1 , l , mid);
                    build(index << 1 | 1 , mid + 1 , r);
                    update(index);
            }
            inline void modify(int index , int l , int r , int val)
            {
                    if (Tree[index].l == l && Tree[index].r == r)
                    {
                            Tree[index].value = val;
                            Tree[index].tag = val;
                            return;
                    }
                    pushdown(index);
                    int mid = (Tree[index].l + Tree[index].r) >> 1;
                    if (mid >= r) modify(index << 1 , l , r , val);
                    else if (mid + 1 <= l) modify(index << 1 | 1 , l , r , val);
                    else
                    {
                            modify(index << 1 , l , mid , val);
                            modify(index << 1 | 1 , mid + 1 , r , val);
                    }
                    update(index);
            }
            inline int query()
            {
                    return Tree[1].value;
            }
            inline int query(int index , int l , int r)
            {
                    if (l > r) return inf;
                    if (Tree[index].l == l && Tree[index].r == r)
                            return Tree[index].value;
                    pushdown(index);
                    int mid = (Tree[index].l + Tree[index].r) >> 1;
                    if (mid >= r) return query(index << 1 , l , r);
                    else if (mid + 1 <= l) return query(index << 1 | 1 , l , r);
                    else return min(query(index << 1 , l , mid) , query(index << 1 | 1 , mid + 1 , r));
            }
    } SGT;
    template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
    template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    inline void addedge(int u , int v)
    {
            ++tot;
            e[tot] = (edge){v , head[u]};
            head[u] = tot;
    }
    inline void dfs1(int u , int father)
    {
            son[u] = 0;
            size[u] = 1;
            depth[u] = depth[father] + 1;
            up[u][0] = father;
            fa[u] = father;
            for (int i = 1; i < MAXLOG; i++) up[u][i] = up[up[u][i - 1]][i - 1];
            for (int i = head[u]; i; i = e[i].nxt)
            {
                    int v = e[i].to;
                    if (v == father) continue;
                    dfs1(v , u);
                    size[u] += size[v];
                    if (son[u] == 0 || size[v] > size[son[u]]) son[u] = v;
            }                
    }
    inline void dfs2(int u , int t)
    {
            dfn[u] = l[u] = ++timer;
            loc[timer] = u;
            top[u] = t;
            if (son[u]) dfs2(son[u] , t);
            for (int i = head[u]; i; i = e[i].nxt)
            {
                    int v = e[i].to;
                    if (v != fa[u] && v != son[u]) dfs2(v , v);        
            }        
            r[u] = timer;
    }
    inline void modify(int u , int v , int w)
    {
            int tu = top[u] , tv = top[v];
            while (tu != tv)
            {
                    if (depth[tu] > depth[tv])    
                    {
                            swap(u , v);
                            swap(tu , tv);        
                    }    
                    SGT.modify(1 , dfn[tv] , dfn[v] , w);
                    v = fa[tv]; tv = top[v];
            }         
            if (dfn[u] > dfn[v]) swap(u , v);
            SGT.modify(1 , dfn[u] , dfn[v] , w);
    }
    
    int main()
    {
            
            read(n); read(q);
            for (int i = 1; i < n; i++)
            {
                    int u , v;
                    read(u); read(v);
                    addedge(u , v);
                    addedge(v , u);
            }
            for (int i = 1; i <= n; i++) read(a[i]);
            read(rt);
            dfs1(rt , 0);
            dfs2(rt , rt);
            SGT.build(1 , 1 , n);
            while (q--)
            {
                    int type;
                    read(type);
                    if (type == 1)
                    {
                            int x;
                            read(x);
                            rt = x;        
                    }    else if (type == 2)
                    {
                            int u , v , w;
                            read(u); read(v); read(w);
                            modify(u , v , w);
                    } else
                    {
                            int x;
                            read(x);
                            if (x == rt) printf("%d
    " , SGT.query());
                            else if (l[x] <= l[rt] && r[x] >= r[rt])
                            {
                                    int y = rt;
                                    for (int i = MAXLOG - 1; i >= 0; i--)
                                    {
                                            if (depth[up[y][i]] > depth[x])
                                                    y = up[y][i];
                                    }
                                    printf("%d
    " , min(SGT.query(1 , 1 , l[y] - 1) , SGT.query(1 , r[y] + 1 , n)));
                            } else printf("%d
    " , SGT.query(1 , l[x] , r[x]));
                    }
            }
            
            return 0;
        
    }
  • 相关阅读:
    centos6.5+mono+nginx跑asp.net
    YYHS-手机信号
    NOIP2017提高组初赛
    BZOJ-4915-简单的数字题
    BZOJ-5055-膜法师(离散化+树状数组)
    YYHS-Super Big Stupid Cross(二分+扫描线+平衡树)
    BZOJ-1008-[HNOI2008]越狱(快速幂)
    BZOJ-1192-[HNOI2006]鬼谷子的钱袋
    POJ-2417-Discrete Logging(BSGS)
    BZOJ-1010-[HNOI2008]玩具装箱toy(斜率优化)
  • 原文地址:https://www.cnblogs.com/evenbao/p/10055811.html
Copyright © 2011-2022 走看看