[Hihocoder week177]Full Binary Tree Picture

来源:互联网 发布:迅捷路由器绑定mac干嘛 编辑:程序博客网 时间:2024/06/05 07:35

Hihocoder Week 177 — Full Binary Tree Picture (O(N)复杂度)

Problem

题目链接

Idea

Some solutions gives by others need to traverse the whole full binary tree and check each nodes to get the answer. Here we put forward a solution whose time complexity is O(N).

The key idea of the solution is to get the count of nodes in the range of [y1, y2] in each layer. If the x coordinate of the layer is in the range of [x1, x2], we will add the count to the answer.

Note that we can mark nodes in a full binary tree with numbers from 1 to 2N1, and the numbers in each layer is a consecutive sequence. Satisfied nodes in one layer form a sub-sequence of the whole sequence. Thus, given start and the end of the satisfied nodes, we can get the count of satisfied nodes. snode and enode denote the start node ant the end node of the satisfied nodes sequence.

In the solution, we use two variables to capture the indexes of snode and enode, i.e., y_min and y_max. Their indexes are stored in y_min_idx and y_max_idx. At the start of the algorithm, we initialize their values as y_min = y_max = 0 and y_min_idx = y_max_idx = 0, for we start to go from the root.

Our algorithm can be divided into two procedures.

  1. In the first procedure, y_min==y_max. And we need to check whether snode and enode can go two side (left child and right child). We can see that only if y_min/y_max is in the range of [y1, y2], we can bi-path snode and enode to left child and right child. This is because the range between them potentially have an intersection with [y1, y2]. Otherwise y_min/y_max is in the outside of [y1, y2]. This time, y_min/y_max need to go close to y1 or y2.

  2. In the second procedure, y_min!=y_max. And we need to check y_min and y_max to make sure whether they are in the range of [y1, y2]. If not, for y_min, snode will go to its right child; for y_max, enode will go to its left child. We have mentioned that [y_min, y_max] may have an intersection with [y1, y2]. If y_min is out of the range, we set temp snode to its right sibling node. If y_max is out of the range, we set temp enode to its left sibling node. If the x coordinate of the current layer is in the range of [x1, x2], we add count of nodes between snode and enode.

The step (height difference) between two adjcent layer is easy to compute, and we omit here.

Code

// time: 0ms, momory: 0MB#include <string.h>#include <stdio.h>int n, m;int x1[110];int y1[110];int x2[110];int y2[110];int height[20];void cal(int a1, int b1, int a2, int b2){    int i;     int ans = 0;    int x = 0;    int y_max = 0;    int y_min = 0;    int y_max_idx = 1;    int y_min_idx = 1;    int tmp_max, tmp_min;    if(a1 > a2 || b1 > b2){        printf("0\n");        return;    }    for(i = 1; i <= n; i++){        if(x > a2)            break;        if(y_min == y_max){            // check whether in the range            if(y_min >= b1 && y_min <= b2){                //good, go two sides                if(x >= a1){                    ans++;                }                y_min -= (height[i] + 1);                y_min_idx = y_min_idx * 2;                y_max += (height[i] + 1);                y_max_idx = y_max_idx * 2 + 1;            } else {                // bad , both go one side                if(y_min < b1) {                    // both go right                    y_min += (height[i] + 1);                    y_min_idx = y_min_idx * 2 + 1;                    y_max += (height[i] + 1);                    y_max_idx = y_max_idx * 2 + 1;                } else {                    // both go left                    y_min -= (height[i] + 1);                    y_min_idx = y_min_idx * 2;                    y_max -= (height[i] + 1);                    y_max_idx = y_max_idx * 2;                }            }        } else {            // has go two side            tmp_max = (y_max > b2) ? (y_max_idx - 1) : y_max_idx;            tmp_min = (y_min < b1) ? (y_min_idx + 1) : y_min_idx;            // if(tmp_max >= tmp_min) {                if(x >= a1){                    ans += (tmp_max - tmp_min + 1);                }            // }            if(y_max > b2){                // go left                y_max -= (height[i] + 1);                y_max_idx = y_max_idx * 2;            } else {                // continue go right                y_max += (height[i] + 1);                y_max_idx = y_max_idx * 2 + 1;            }            if(y_min < b1) {                // go right                y_min += (height[i] + 1);                y_min_idx = y_min_idx * 2 + 1;            } else {                // continue go left                y_min -= (height[i] + 1);                y_min_idx = y_min_idx * 2;            }        }        x += (height[i] + 1);    }    printf("%d\n", ans);}void solve(){    int i;    memset(height, 0, sizeof(height));    // calculate layer step    if(n > 1)        height[n-1] = 1;    if(n > 2)        height[n-2] = 2;    for(i = n-3; i >= 1; i--){        // for(int j = n-1; j > i; j--){        //  height[i] += (height[j] + 1);        // }        height[i] = height[i+1] * 2 + 1;    }    for(int i = 0; i < m; i++){        cal(x1[i], y1[i], x2[i], y2[i]);    }}int main(int argc, char const *argv[]){    int i;#ifndef ONLINE_JUDGE    freopen("out", "r", stdin);#endif    scanf("%d %d", &n, &m);    for(i = 0; i < m; i++){        // cin >> x1[i] >> y1[i] >> x2[i] >> y2[i];        scanf("%d %d %d %d", &x1[i], &y1[i], &x2[i], &y2[i]);    }    solve();    return 0;}
阅读全文
0 0
原创粉丝点击