zoukankan      html  css  js  c++  java
  • SPOJ 375 树链剖分

    SPOJ太慢了,SPOJ太慢了,

    题意:给定n(n<=10000)个节点的树,每条边有边权,有两种操作:1.修改某条变的边权;2.查询u,v之间路径上的最大边权。

    分析:树链剖分入门题,看这里:http://blog.sina.com.cn/s/blog_6974c8b20100zc61.html

    轻重链剖分,线段树维护,复杂度 O(nlogn + q* logn * logn )

    SPOJ太慢了,我知道我写的应该是没错了,

    最后把自己宏定义的max和min去掉之后终于过了,傻逼笑呵呵了。。为啥宏定义max,min占用这么长时间,求指教。

    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <cstring>
    using namespace std;
    #define maxn 10010
    
    int w[maxn],son[maxn],sz[maxn],top[maxn],fa[maxn],dep[maxn];
    int d1[maxn][3];
    int z;
    int n ;
    char str[15];
    struct node
    {
        int v ,next;
    };
    
    node e[maxn * 2 ];
    int cnt ;
    int head[maxn];
    int tt[maxn * 3 ];
    
    inline void add(int u ,int v)
    {
        e[cnt].v = v;
        e[cnt].next = head[u];
        head[u] = cnt ++ ;
        return ;
    }
    void push_up(int root )
    {
        tt[root] = max(tt[root*2],tt[root*2+1]);
    }
    inline void dfs1(int u )  // 计算 sz[],son[],dep[],fa[];
    {
        sz[u] = 1 ;
        son[u] = 0;
        for(int i = head[u] ; i != -1 ; i = e[i].next)
            if(e[i].v != fa[u])
            {
                fa[e[i].v] = u;
                dep[e[i].v] = dep[u] + 1;
                dfs1(e[i].v);
                if(sz[e[i].v] > sz[son[u]] )  son[u] = e[i].v;
                sz[u] += sz[e[i].v];
            }
    }
    
    void dfs2(int u,int tp) // 计算 w[],top[]
    {
        w[u] = ++ z ;
        top[u] = tp;
        if(son[u] != 0 ) dfs2(son[u] , top[u]);
        for(int i = head[u] ; i!= -1 ;i = e[i].next)
        if(e[i].v != fa[u] && e[i].v != son[u] )
            dfs2(e[i].v,e[i].v);
        return ;
    }
    void update(int root,int l,int r,int pos,int val)
    {
        if(l == r )
        {
            tt[root] = val;
            return ;
        }
        int mid = (l + r ) / 2;
        if(pos <= mid)
            update(root + root ,l,mid, pos , val);
        else
            update(root + root  + 1 ,mid +1 , r , pos ,val);
        push_up(root);
        return ;
    }
    int query(int root,int l1,int r1,int l,int r)
    {
        if(l <= l1 && r1 <= r)
             return tt[root];
        int mid = (l1 + r1 ) / 2 ;
        int res = 0 ;
        if(l <= mid )
            res = max(res , query(root + root,l1 , mid , l , r ));
        if(r > mid )
            res = max(res , query(root + root + 1 ,mid + 1 , r1 , l , r ));
        return res;
    }
    int find(int a,int b)
    {
        int f1 = top[a] , f2 = top[b] , tmp = 0 ;
        while( f1 != f2 )
        {
            if(dep[f1] < dep[f2])
                swap(f1,f2),swap(a,b);
            tmp = max(tmp , query(1,1,z,w[f1],w[a]) );
            a = fa[f1],f1 = top[a];
        }
        if(a == b) return tmp ;
        if(dep[a] > dep[b]) swap(a,b);
        return max(tmp , query(1,1,z,w[son[a]],w[b]) ); // 父边
    }
    
    int main()
    {
        int root;
        int u,v,w1;
        int cas;
        scanf("%d",&cas);
        while(cas -- )
        {
            scanf("%d",&n);
            cnt = 0 ;
            memset(head,-1,sizeof(head));
            memset(tt,0,sizeof(tt));
            for(int i = 1 ; i < n ; i ++ )
            {
                scanf("%d%d%d",&u,&v,&w1);
                d1[i][0] = u;
                d1[i][1] = v;
                d1[i][2] = w1;
                add(u,v);
                add(v,u);
            }
            root = 1;
            dep[root] = 0 ;
            fa[root] = 0 ;
            dfs1(root);
            z = 0 ;
            dfs2(root,root);
            for(int i = 1 ; i < n ; i ++ )
            {
                if(dep[d1[i][0]] > dep[d1[i][1]] ) swap(d1[i][0],d1[i][1]);
                update(1,1,z,w[d1[i][1]] ,d1[i][2]);
            }
            scanf("%s",str);
            while(str[0] != 'D')
            {
                scanf("%d%d",&u,&v);
                if(str[0] == 'Q')
                    printf("%d
    ",find(u,v));
                else update(1,1,z,w[d1[u][1]],v);
                scanf("%s",str);
            }
        }
        return 0;
    }
    /*
        tle
        建树费时删去->tle
        // luangao -> tle
        去掉自己宏定义的max和min -> AC!!!!!!!!!!!!
    */
    View Code

    据说这题还可用link_cut tree做,论文没看懂。。。

    看这里 QTREE解法的一些研究

    这类问题是动态树问题:算法合集之《动态树问题及其应用》 ,也没看懂。。。。

  • 相关阅读:
    大一C语言结课设计之《学生信息管理系统》
    HDU1003 Max Sum(求最大字段和)
    ORACLE AUTOMATIC STORAGE MANAGEMENT翻译-第二章ASM Instance(4)完
    System.setProperty()
    分布式存储系统sheepdog
    c语言全局变量和局部变量问题汇总
    excel VLOOKUP函数的用法
    现有一些开源ESB总线的比較
    POJ 3624 Charm Bracelet
    H.264远程视频监控系统
  • 原文地址:https://www.cnblogs.com/jh818012/p/3251455.html
Copyright © 2011-2022 走看看