zoukankan      html  css  js  c++  java
  • POJ 2763 Housewife Wind (树链剖分)

    题目链接~~>

    做题感悟:这题说多了都是泪啊 !明明是一个简单的不能再简单的树链剖分。结果由于一个符号错误找了一下午大哭

    解题思路:

                      树链剖分 + 线段树插点问线

    代码:

    #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 long long int
    #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 = 1400 + 5 ;
    const int MX = 100000 + 5 ;
    int n ,m ,idx ,num ,st ;
    int head[MX] ,ti[MX] ,dep[MX] ,top[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 ,sum ;
    }T[MX*4] ;
    void build(int x ,int le ,int rt)
    {
        T[x].le = le ; T[x].rt = rt ;
        T[x].sum = 0 ;
        if(le == rt)  return ;
        int Mid = (le + rt)>>1 ;
        build(L(x) ,le ,Mid) ;
        build(R(x) ,Mid+1 ,rt) ;
    }
    void update(int x ,int pos ,int w)
    {
        if(T[x].le == T[x].rt)
        {
            T[x].sum = w ;
            return ;
        }
        int Mid = (T[x].le + T[x].rt)>>1 ;
        if(pos <= Mid)    update(L(x) ,pos ,w) ;
        else     update(R(x) ,pos ,w) ;
        T[x].sum = T[L(x)].sum + T[R(x)].sum ;
    }
    int Query(int x ,int le ,int rt)
    {
        if(T[x].le == le && T[x].rt == rt)
            return T[x].sum ;
        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 Query(L(x) ,le ,Mid) + Query(R(x) ,Mid+1 ,rt) ;
    }
    int LCA(int u ,int v)
    {
        int ans = 0 ;
        while(top[u] != top[v])
        {
            if(dep[top[u]] < dep[top[v]])
                swap(u ,v) ;
            ans += Query(1 ,ti[top[u]] ,ti[u]) ;
            u = father[top[u]] ;
        }
        if(dep[u] > dep[v])
            swap(u ,v) ;
        if(u != v)
             ans += Query(1 ,ti[u]+1 ,ti[v]) ;
        return ans ;
    }
    int main()
    {
        //freopen("input.txt" ,"r" ,stdin) ;
        int c ,u ,w ;
        while(~scanf("%d%d%d" ,&n ,&m ,&st))
        {
            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] = siz[0] = 0 ;
            dfs_find(1 ,1) ;
            idx = 1 ;
            dfs_time(1 ,1) ;
            build(1 ,1 ,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) ;
            }
            for(int i = 0 ;i < m ; ++i)
            {
                scanf("%d%d" ,&c ,&u) ;
                if(c)
                {
                    scanf("%d" ,&w) ;
                    update(1 ,ti[e[u].u] ,w) ;
                }
                else
                {
                    printf("%d
    " ,LCA(st ,u)) ;
                    st = u ;
                }
            }
        }
        return 0 ;
    }
    


  • 相关阅读:
    C语言 sprintf 函数 C语言零基础入门教程
    C语言 printf 函数 C语言零基础入门教程
    C语言 文件读写 fgets 函数 C语言零基础入门教程
    C语言 文件读写 fputs 函数 C语言零基础入门教程
    C语言 fprintf 函数 C语言零基础入门教程
    C语言 文件读写 fgetc 函数 C语言零基础入门教程
    C语言 文件读写 fputc 函数 C语言零基础入门教程
    C语言 strlen 函数 C语言零基础入门教程
    Brad Abrams关于Naming Conventions的演讲中涉及到的生词集解
    适配器模式
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6755927.html
Copyright © 2011-2022 走看看