• POJ 3237 Tree (树链拆分)


    主题链接~~>

    做题情绪:了。

    解题思路:

                   主要注意如何区间更新就ok了 。

    树链剖分就是树上的线段树。

    代码:

    #include<iostream>
    #include<sstream>
    #include<map>
    #include<cmath>
    #include<fstream>
    #include<queue>
    #include<vector>
    #include<sstream>
    #include<cstring>
    #include<cstdio>
    #include<stack>
    #include<bitset>
    #include<ctime>
    #include<string>
    #include<cctype>
    #include<iomanip>
    #include<algorithm>
    using namespace std  ;
    #define INT __int64
    #define L(x)  (x * 2)
    #define R(x)  (x * 2 + 1)
    const int INF = 0x3f3f3f3f ;
    const double esp = 0.0000000001 ; 
    const double PI = acos(-1.0) ;
    const int mod = 1e9 + 7 ;
    const int MY = 1e7 + 5 ;
    const int MX = 10000 + 5 ;
    int n ,num ,idx ;
    int head[MX] ,dep[MX] ,top[MX] ,ti[MX] ,siz[MX] ,son[MX] ,father[MX] ;
    struct NODE
    {
        int u ,v ,w ;
    }e[MX] ;
    struct Edge
    {
        int v ,next ;
    }E[MX*2] ;
    void addedge(int u ,int v)
    {
        E[num].v = v ; E[num].next = head[u] ; head[u] = num++ ;
        E[num].v = u ; E[num].next = head[v] ; head[v] = num++ ;
    }
    void dfs_find(int u ,int fa)
    {
        dep[u] = dep[fa] + 1 ;
        siz[u] = 1 ;
        son[u] = 0 ;
        father[u] = fa ;
        for(int i = head[u] ;i != -1 ;i = E[i].next)
        {
            int v = E[i].v ;
            if(v == fa)   continue ;
            dfs_find(v ,u) ;
            siz[u] += siz[v] ;
            if(siz[son[u]] < siz[v]) son[u] = v ;
        }
    }
    void dfs_time(int u ,int fa)
    {
        ti[u] = idx++ ;
        top[u] = fa ;
        if(son[u])    dfs_time(son[u] ,top[u]) ;
        for(int i = head[u] ;i != -1 ;i = E[i].next)
        {
            int v = E[i].v ;
            if(v == father[u] || v == son[u])  continue ;
            dfs_time(v ,v) ;
        }
    }
    struct node
    {
        int le ,rt ,Mi ,Mx ,add ;
    }T[MX*4] ;
    void build(int x ,int le ,int rt)
    {
        T[x].le = le ; T[x].rt = rt ;
        T[x].Mi = INF ; T[x].Mx = -INF ;
        T[x].add = 0 ;
        if(le == rt)  return ;
        int Mid = (le + rt)>>1 ;
        build(L(x) ,le ,Mid) ;
        build(R(x) ,Mid+1 ,rt) ;
    }
    void push_down(int x)
    {
        if(T[x].le == T[x].rt)  return ;
        if(T[x].add)
        {
            T[L(x)].Mi = -T[L(x)].Mi ;
            T[L(x)].Mx = -T[L(x)].Mx ;
            swap(T[L(x)].Mi ,T[L(x)].Mx) ;
            T[R(x)].Mi = -T[R(x)].Mi ;
            T[R(x)].Mx = -T[R(x)].Mx ;
            swap(T[R(x)].Mi ,T[R(x)].Mx) ;
            T[L(x)].add ^= 1 ;
            T[R(x)].add ^= 1 ;
            T[x].add = 0 ;
        }
    }
    void push_up(int x)
    {
        T[x].Mi = min(T[L(x)].Mi ,T[R(x)].Mi) ;
        T[x].Mx = max(T[L(x)].Mx ,T[R(x)].Mx) ;
    }
    void section(int x ,int le ,int rt)  // 更新某个区间
    {
        if(T[x].le == le && T[x].rt == rt)
        {
            T[x].add ^= 1 ;  
            T[x].Mi = -T[x].Mi ;
            T[x].Mx = -T[x].Mx ;
            swap(T[x].Mi ,T[x].Mx) ;
            return ;
        }
        if(T[x].le == T[x].rt)  return ;
        push_down(x) ;
        int Mid = (T[x].le + T[x].rt)>>1 ;
        if(le > Mid)
                section(R(x) ,le ,rt) ;
        else if(rt <= Mid)
                section(L(x) ,le ,rt) ;
        else
        {
            section(L(x) ,le ,Mid) ;
            section(R(x) ,Mid+1 ,rt) ;
        }
        push_up(x) ;
    }
    void update(int x ,int pos ,int w)
    {
        if(T[x].le == T[x].rt)
        {
            T[x].Mi = w ;
            T[x].Mx = w ;
            T[x].add = 0 ;
            return ;
        }
        push_down(x) ;
        int Mid = (T[x].le + T[x].rt)>>1 ;
        if(pos <= Mid)
                 update(L(x) ,pos ,w) ;
        else     update(R(x) ,pos ,w) ;
        push_up(x) ;
    }
    int Query(int x ,int le ,int rt)  // 询问某个区间
    {
        if(T[x].le == le && T[x].rt == rt)
           return  T[x].Mx ;
        push_down(x) ;
        int Mid = (T[x].le + T[x].rt)>>1 ;
        if(le > Mid)
              return Query(R(x) ,le ,rt) ;
        else if(rt <= Mid)
              return Query(L(x) ,le ,rt) ;
        else
              return max(Query(L(x) ,le ,Mid) ,Query(R(x) ,Mid+1 ,rt)) ;
        push_up(x) ;
    }
    int LCA(int u ,int v)
    {
        if(u == v)  return 0 ;
        int ans = -INF ;
        while(top[u] != top[v])
        {
            if(dep[top[u]] < dep[top[v]])
                  swap(u ,v) ;
            ans = max(ans ,Query(1 ,ti[top[u]] ,ti[u])) ;
            u = father[top[u]] ;
        }
        if(dep[u] > dep[v])
             swap(u ,v) ;
        if(u != v)
               ans = max(ans ,Query(1 ,ti[u]+1 ,ti[v])) ;
        return ans ;
    }
    void change(int u ,int v)
    {
        while(top[u] != top[v])
        {
            if(dep[top[u]] < dep[top[v]])
                 swap(u ,v) ;
            section(1 ,ti[top[u]] ,ti[u]) ;
            u = father[top[u]] ;
        }
        if(dep[u] > dep[v])
              swap(u ,v) ;
        section(1 ,ti[u]+1 ,ti[v]) ;
    }
    int main()
    {
       int Tx ;
       scanf("%d" ,&Tx) ;
       while(Tx--)
       {
           scanf("%d" ,&n) ;
           num = 0 ;
           memset(head ,-1 ,sizeof(head)) ;
           for(int i = 1 ;i < n ; ++i)
           {
               scanf("%d%d%d" ,&e[i].u ,&e[i].v ,&e[i].w) ;
               addedge(e[i].u ,e[i].v) ;
           }
           dep[1] = 0 ; siz[0] = 0 ;
           dfs_find(1 ,1) ;
           idx = 1 ;
           dfs_time(1 ,1) ;
           build(1 ,2 ,n) ;
           for(int i = 1 ;i < n ; ++i)
           {
               if(dep[e[i].u] < dep[e[i].v])
                     swap(e[i].u ,e[i].v) ;
               update(1 ,ti[e[i].u] ,e[i].w) ;
           }
           int x ,y ;
           char s[10] ;
           while(true)
           {
               scanf("%s" ,s) ;
               if(s[0] == 'D')  break ;
               scanf("%d%d" ,&x ,&y) ;
               if(s[0] == 'C')
                       update(1 ,ti[e[x].u] ,y) ;
               else if(s[0] == 'N')
                       change(x ,y) ;
               else if(s[0] == 'Q')
                       cout<<LCA(x ,y)<<endl ;
           }
       }
       return 0 ;
    }
    



    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    【DFS】算24点
    【位运算】【BFS】移动玩具
    【并查集】【DFS】搭桥
    shell脚本编写informix数据库中表的导入和导出
    利用springloaded进行java jar&class的动态替换
    利用springloaded进行java class动态替换
    ActiveMq unsupported major.minor version 52.0
    oracle主键修改&设置某一字段可以为null
    XStream将XML转javaben,出现多余的tag,导致出错
    oracle:the password has expired
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4837830.html
Copyright © 2020-2023  润新知