hdu 1754 I Hate It

第一次做线段树的入门题目,写很多次都超时,最后发现是我的宏定义的问题

#define max(a, b) (a) > (b) ? a : b

在queryTree()中当要询问的区间在左右区间的时候

我起初写:

    return max(queryTree(left, mid, LL), queryTree(mid + 1, right, RR));

结果一直超时,很是郁闷!!!

最后改成:

      int a = queryTree(left, mid, LL);

      int b = queryTree(mid + 1, right, RR);

      return max(a, b);

然后果断AC了用时500ms。

思考许久后发现这个是宏定义的问题,宏定义在预编译的时候进行字符替换。

第一种写法替换后变成:

     queryTree(left, mid, LL) > queryTree(mid + 1, right, RR) ? queryTree(left, mid, LL) : queryTree(mid + 1, right, RR);

第二种写法替换后变成:

     a > b ? a : b;

显然第一种写法queryTree多调用了2次必然超时。

/* Author: ACb0y Date: 2010-9-05 Type: segment tree ProblemId: hdu 1754 I Hate It Result: 2921276 2010-09-05 17:19:40 Accepted 1754 500MS 7156K 2837 B C++ ACb0y */ #include <iostream> using namespace std; #define max(a, b) (a) > (b) ? a : b #define MAX 200005 //节点信息 struct node { //left->right区间 int left; int right; //区间内的最大值 int maxValue; int get_mid() { return (left + right) >> 1; } }; int n, m; //叶子节点的值 int score[MAX]; //完全二叉树(segment tree) node tree[MAX * 3]; //建树 int buildTree(int left, int right, int loc) { //左子树 int LL = loc << 1; //右子树 int RR = LL | 1; tree[loc].left = left; tree[loc].right = right; //如果是叶子节点 if (left == right) { return tree[loc].maxValue = score[left]; } int mid = tree[loc].get_mid(); //建左子树 buildTree(left, mid, LL); //建右子树 buildTree(mid + 1, right, RR); //求根的maxValue值 tree[loc].maxValue = max(tree[LL].maxValue, tree[RR].maxValue); } //更新树 int updateTree(int id, int value, int loc) { int LL = loc << 1; int RR = LL | 1; //找到要更新的子节点 if (tree[loc].left == tree[loc].right && tree[loc].left == id) { return tree[loc].maxValue = value; } int mid = tree[loc].get_mid(); //更新左子树 if (id <= mid) { updateTree(id, value, LL); } //更新右子树 else { updateTree(id, value, RR); } //更新根的maxValue值 tree[loc].maxValue = max(tree[LL].maxValue, tree[RR].maxValue); } //询问某个区间内的最大值 int queryTree(int left, int right, int loc) { //左子树 int LL = loc << 1; //右子树 int RR = LL | 1; //找到要询问的区间 if (tree[loc].left == left && tree[loc].right == right) { return tree[loc].maxValue; } int mid = tree[loc].get_mid(); //要询问的区间在左子树 if (right <= mid) { return queryTree(left, right, LL); } //要询问的区间在右子树 else if (mid < left) { return queryTree(left, right, RR); } //要询问的区间分别位于左右子树 else { int a = queryTree(left, mid, LL); int b = queryTree(mid + 1, right, RR); return max(a, b); } } int main() { int i; while (scanf("%d%d", &n, &m) != EOF) { for (i = 1; i <= n; i++) { scanf("%d", &score[i]); } char op[2]; int a; int b; buildTree(1, n, 1); for (i = 1; i <= m; i++) { scanf("%s%d%d", op, &a, &b); if (op[0] == 'U') { updateTree(a, b, 1); } else { printf("%d/n", queryTree(a, b, 1)); } } } return 0; }

 

  

 

 

你可能感兴趣的:(c,struct,tree,2010)