SPOJ GSS1 WA - 段树

时间:2012-08-10 09:29:09

标签: c++ segment-tree

我正在尝试使用GSS1解决SPOJ问题segment tree(您能否回答这些问题)。我正在使用'init'方法来初始化树和'query'方法以在[i,j]范围内获得最大值。

限制| A [i] | < = 15707且1< = N(元素数)< = 50000。

int A[50500], tree[100500];

void init(int n, int b, int e) // n=1, b=lower, e=end
{
    if(b == e)
    {
        tree[n] = A[b];
        return;
    }
    init(2 * n, b, (b + e) / 2);
    init(2 * n + 1, ((b + e) / 2) + 1, e);

    tree[n] = (tree[2 * n] > tree[2 * n + 1]) ? tree[2 * n] : tree[2 * n + 1];
}

int query(int n, int b, int e, int i, int j) // n=1, b=lower, e=end, [i,j]=range
{
    if(i>e || j<b) 
        return -20000;
    if(b>=i && e<=j)  
        return tree[n];

    int p1 = query(2 * n, b, (b + e) / 2, i, j);
    int p2 = query(2 * n + 1, ((b + e) / 2) + 1, e, i, j);

    return (p1 > p2) ? p1 : p2;
}

程序正在提供错误的答案。我为大多数情况(负数,奇数/偶数N)的代码进行了修改,但我无法弄清楚算法有什么问题。

如果有人能指出我正确的方向,我将不胜感激。

由于

2 个答案:

答案 0 :(得分:1)

我担心(接受的)答案错过了一个非常重要的观点。问题在于代码本身使用的算法。代码说节点的答案是其子节点的最大值。但是最大的子阵列很可能部分地存在于两个孩子中。例如

-1 -2 3 4 5 6 -5 -10(n = 8)

代码输出11而答案是18。

您还需要调查此案例以击败WA。 (我正在回答这个问题,因为接受的答案并不完全正确,并且没有正确回答这个问题。)

答案 1 :(得分:0)

编辑:看来您的实施也是正确的,我只是另一个。我们都误解了问题陈述。


我猜你用params调用你的query函数

query( 1, 0, n-1, x-1, y-1 );

我认为当你的n不是2的幂时,以这种方式处理分段树是错误的。
我要你

  1. tree数组放大到131072个元素(2 ^ 17)和A到65536(2 ^ 16);
  2. 发现最小的k不小于n并且是2的幂;
  3. 使用-20000初始化n(从0开始)到k-1的元素;
  4. 使n等于k;
  5. 请务必致电init(1,0,n-1);
  6. 希望能帮助你击败西澳大利亚州。