zoukankan      html  css  js  c++  java
  • POJ3764 The xorlongest Path

    这是道感觉很不错的题。武森09年的论文中有道题CowXor,求的是线性结构上的,连续序列的异或最大值,用的办法是先预处理出前n项的异或值,然后在这些值中找出两个值的异或值最大。是基于这样的一个原理,相同段的异或值为0。而这道题把它扩展到树上,这也提示了我们,在思考问题的时候,可以把它退化一维去考虑,即从一般到特殊,出题的时候把它升一维。当时比赛的时候,对这道题都不敢去思考,去分析。因此要习惯分析难题,学会去分析,当然多做题,多思考把自己的思维拓宽很重要。然后对于找两个值的异或值最大,最暴力就是枚举,n^2的复杂度,肯定不行,论文中给出了nlgn的复杂度,方法是枚举每个数,把数插入到一颗高度为logn的树中,这是个只有01的编码树,然后对于每个插入的数的二进制表示,在这颗树上匹配,由于数存放的时候是从高位到低位,因此,每次能走不同的就走不同的,这样能保证异或出来的值查询的数与树中的数最大的异或值。预处理的办法是对树DFS一般就可以,感觉这样的方法很巧妙,很多大牛都说显然,大牛就是大牛。

    用静态数组吧,之前动态分配,TLE。

    感谢:

    http://blog.csdn.net/yuhailin060/archive/2010/05/10/5576255.aspx

    代码
    #include <iostream>
    #include
    <string>
    #include
    <vector>
    #include
    <math.h>
    using namespace std;

    const int MAX = 100005;

    struct NODE
    {
    int to, value;
    //NODE* next;
    int next;
    NODE() {}
    //NODE(int vv, NODE* pp, int tt) : value(vv), next(pp), to(tt) {}
    NODE(int vv, int pp, int tt) : value(vv), next(pp), to(tt) {}
    };
    //

    NODE node[
    3 * MAX];
    int nodetop;

    struct newNODE
    {
    //newNODE* to[2];
    int to[2];
    int end;
    newNODE()
    {
    //to[0] = to[1] = NULL;
    to[0] = to[1] = -1;
    end
    = -1;
    }
    };
    //*root;

    newNODE newnode[
    20 * MAX];
    int newtop;

    int root;

    //NODE* mm[MAX];
    int mm[MAX];

    int n, ans;

    void add(int a, int b, int c)
    {
    //NODE* p = mm[a];
    int p = mm[a];
    mm[a]
    = nodetop;
    node[nodetop
    ++] = NODE(c, p, b);
    //mm[a] = new NODE(c, p , b);
    }

    void insert(int myxor)
    {
    //newNODE* p = root;
    int p = root;
    for(int i = 30; i >= 0; i--)
    {
    if((1 << i) & myxor)
    {
    //当前位是1
    //if(p->to[1] == NULL) p->to[1] = new newNODE();
    if(newnode[p].to[1] == -1)
    {
    newnode[p].to[
    1] = newtop;
    newnode[newtop
    ++] = newNODE();
    }
    //p = p->to[1];
    p = newnode[p].to[1];
    }
    else
    {
    //当前位是0
    //if(p->to[0] == NULL) p->to[0] = new newNODE();
    if(newnode[p].to[0] == -1)
    {
    newnode[p].to[
    0] = newtop;
    newnode[newtop
    ++] = newNODE();
    }
    //p = p->to[0];
    p = newnode[p].to[0];
    }
    }
    //标记插入的数值
    //p->end = myxor;
    newnode[p].end = myxor;
    }

    void query(int myxor)
    {
    //newNODE* p = root;
    int p = root;
    for(int i = 30; i >= 0; i--)
    {
    if((1 << i) & myxor)
    {
    //当前位是1
    //if(p->to[0] != NULL) p = p->to[0];
    if(newnode[p].to[0] != -1) p = newnode[p].to[0];
    //else p = p->to[1];
    else p = newnode[p].to[1];
    }
    else
    {
    //当前位是0
    //if(p->to[1] != NULL) p = p->to[1];
    if(newnode[p].to[1] != -1) p = newnode[p].to[1];
    //else p = p->to[0];
    else p = newnode[p].to[0];
    }
    }
    //ans = max(ans, (myxor ^ (p->end)));
    ans = max(ans, myxor ^ newnode[p].end);
    }

    void dfs(int u, int f, int myxor)
    {
    //printf("#%d->%d\n", u, myxor);
    //把值插入到树上
    insert(myxor);
    //到树上贪心查询
    query(myxor);
    //for(NODE* i = mm[u]; i; i = i->next)
    for(int i = mm[u]; i != -1; i = node[i].next)
    {
    //int v = (*i).to;
    int v = node[i].to;
    //int w = (*i).value;
    int w = node[i].value;
    if(v != f)
    {
    dfs(v, u, (myxor
    ^ w));
    }
    }
    }

    int go()
    {
    ans
    = 0;
    //root = new newNODE();
    nodetop = 0;
    newtop
    = 1;
    root
    = 0;
    newnode[root]
    = newNODE();
    dfs(
    0, -1, 0);
    return ans;
    }

    int main()
    {
    while(scanf("%d", &n) != EOF)
    {
    //memset(mm, NULL, sizeof(mm));
    memset(mm, -1, sizeof(mm));
    for(int i = 1; i < n; i++)
    {
    int a, b, c;
    scanf(
    "%d%d%d", &a, &b, &c);
    add(a, b, c);
    add(b, a, c);
    }
    printf(
    "%d\n", go());
    }
    }
  • 相关阅读:
    hdu 1199 Color the Ball 离散线段树
    poj 2623 Sequence Median 堆的灵活运用
    hdu 2251 Dungeon Master bfs
    HDU 1166 敌兵布阵 线段树
    UVALive 4426 Blast the Enemy! 计算几何求重心
    UVALive 4425 Another Brick in the Wall 暴力
    UVALive 4423 String LD 暴力
    UVALive 4872 Underground Cables 最小生成树
    UVALive 4870 Roller Coaster 01背包
    UVALive 4869 Profits DP
  • 原文地址:https://www.cnblogs.com/litstrong/p/1788218.html
Copyright © 2011-2022 走看看