HDU 3277 city horizon (line segment tree + discretization)

Source: Internet
Author: User

Question link: http://poj.org/problem? Id = 3277

This is my first question of discretization and the combination of line tree in the real sense. After a long time, I continuously patch and finally AC. I have learned a lot from this question.

1. The idea of discretization

2. the array subscript build method of the Line Segment tree (all previous methods used to create a tree with pointers on the array)

3. L> 1 + 1 is to do 1 + 1 first, that is, L> 1 + 1 <=> L> 2. It has been pitted for a long time, so do not take operators that are not very familiar with them for granted.

4. It is easier to create a line segment tree by array subscript and the method of creating a tree by array subscript under the corresponding operation conditions to run the program faster (not the array subscript is faster, but the operation is simpler)

I started to look at this question and never understood how discretization was going. But now I understand that there are so many Integer Points in a straight line. If we want to build a line segment tree in one unit

If the time-out period is not mentioned, you cannot open the memory. Considering that the number of given rectangles is limited, discretization means that you don't understand discretization at first, but you don't understand why it works. Now you understand it.

First, sort all online vertices, and then create a range based on these vertices. Think about the following of all the rectangles only between these vertices, that is, I just need to edit these points from left to right.

And then create a line segment tree. Then, you can use binary search to find the numbers corresponding to the left and right subscripts of the rectangle and then update the range.

It should be well understood.

In the following program, I think this code still needs to be explained:

If (re_root [root]. L + 1! = Re_root [root]. R & re_root [root]. H! =-1)
Re_root [root <1]. H = re_root [(root <1) + 1]. H = re_root [root]. h, re_root [root]. H =-1;

The above code is a piece of code pulled down during the insertion process. When the entire large range is root, if the next update involves this range, it is not the whole range.

Then, the unupdated H will be pulled down, because a section of the current range is not h, so we need to pull down and change the H of this range to-1,

In fact, "-1" means to tell you to query down when querying. Either there is no rectangle in this interval, or there is a rectangle with different heights (the height is 0 and the height is not

A rectangle with a height of 0 is also regarded as a rectangle of different heights)

During insertion, the height is sorted from small to large, which saves time during insertion. In fact, it is no big deal to sort without sorting!

The AC code for creating the line tree by array subscript (modified by pointer version ):

# Include <iostream> # include <string. h> # include <algorithm> # include <stdio. h> using namespace STD; # define maxn 440004 struct point {long l, R, H;} org [maxn]; struct node {long l, R; long long h;} re_root [maxn]; long n; long cut [maxn * 3]; bool CMP1 (const point & A, const point & B) {return. h <B. h;} long Pos; int build_tree (long root, long l, long R) {re_root [root]. L = L, re_root [Root]. R = r; re_root [root]. H =-1; if (L + 1 = r) return 0; long mid = (L + r)> 1; build_tree (root <1, l, mid); build_tree (root <1) + 1, mid, R); // return 0;} int find_num (long l, long R, long long num) {long mid; while (L <= r) {mid = (L + r)> 1; if (cut [Mid] = num) return mid; If (cut [Mid]> num) r = mid-1; else l = Mid + 1;} return 0;} int insert (long root, long long l, long R, long num) {If (Num <= Re_root [root]. h) Return 0; If (re_root [root]. L = L & re_root [root]. R = r) {re_root [root]. H = num; return 0;} If (re_root [root]. L + 1! = Re_root [root]. R & re_root [root]. H! =-1) re_root [root <1]. H = re_root [(root <1) + 1]. H = re_root [root]. h, re_root [root]. H =-1; if (re_root [root]. L + 1 = re_root [root]. r) return 0; long mid = (re_root [root]. L + re_root [root]. r)> 1; if (r <= mid) insert (root <1, L, R, num); else if (L> = mid) insert (root <1) + 1, L, R, num); else insert (root <1, L, mid, num ), insert (root <1) + 1, mid, R, num); Return 0;} long find_ans (long root) {If (re_root [root]. h! =-1) {// printf ("% LLD \ n", cut [re_root [root]. r], cut [re_root [root]. l], re_root [root]. h); Return (long) (cut [re_root [root]. r]-cut [re_root [root]. l]) * re_root [root]. h);} If (re_root [root]. L + 1 = re_root [root]. r) return 0; long mid = (re_root [root]. L + re_root [root]. r)> 1; return find_ans (root <1) + find_ans (root <1) + 1);} int main () {long I, j, k, R, L; while (scanf ("% LLD", & N )! = EOF) {k = 0; Pos = 1; for (I = 0; I <n; I ++) {scanf ("% LLD ", & ORG [I]. l, & ORG [I]. r, & ORG [I]. h); cut [k ++] = org [I]. l, cut [k ++] = org [I]. r;} Sort (cut, cut + k); sort (ORG, org + N, CMP1); r = 1; for (I = 1; I <K; I ++) if (cut [I]! = Cut [I-1]) Cut [R ++] = cut [I]; k = r; build_tree (, k-1); for (I = 0; I <N; I ++) {L = find_num (0, K-1, org [I]. l); r = find_num (0, K-1, org [I]. r); insert (1, L, R, org [I]. h);} printf ("% LLD \ n", find_ans (1);} return 0 ;}

The TLE code of the pointer:

#include <iostream>#include <string.h>#include <algorithm>#include <stdio.h>using namespace std;#define maxn 440004struct point{    long long l,r,h;}org[maxn];struct node{    long long L,R;    long long  h;    node *left,*right;}re_root[maxn];long long  n;long long cut[maxn*3];bool cmp1(const point &a,const point &b){    return a.h < b.h;}long long  pos;int build_tree(node *root){    if(root->L+1 == root->R)    return 0;    long long  mid=(root->L+root->R)>>1;    root->left=&re_root[pos];    re_root[pos].h=-1,re_root[pos].L=root->L,re_root[pos++].R=mid;    build_tree(root->left);    root->right=&re_root[pos];    re_root[pos].L=mid,re_root[pos].R=root->R,re_root[pos++].h=-1;    build_tree(root->right);    return 0;}int find_num(long long  l,long long r,long long  num){    long long  mid;    while(l<=r)    {        mid=(l+r)>>1;        if(cut[mid]==num)        return mid;        if(cut[mid]>num)        r=mid-1;        else        l=mid+1;    }    return 0;}int insert(node *root,long long l,long long  r,long long  num){    if(root->h >= num)    return 0;    if(root->L+1 == root->R)    {        root->h=num;        return 0;    }if(root->L+1!=root->R && root->h !=-1)root->left->h=root->right->h=root->h,root->h=-1;    long long  mid=(root->L + root->R)>>1;    if(r <= mid)    insert(root->left,l,r,num);    else if(l>=mid)    insert(root->right,l,r,num);    else    insert(root->left,l,mid,num),insert(root->right,mid,r,num);    return 0;}long long  find_ans(node *root){    if(root->h!=-1)    {        return ((long long)(cut[root->R]-cut[root->L])*root->h);    }    if(root->L+1 == root->R)    return 0;    long long mid=(root->L+root->R)>>1;    return find_ans(root->left)+find_ans(root->right);}int main(){    long long  i,j,k,r,l;    while(scanf("%lld",&n)!=EOF)    {        k=0;        pos=1;        for(i=0;i<n;i++)        {            scanf("%lld%lld%lld",&org[i].l,&org[i].r,&org[i].h);            cut[k++]=org[i].l,cut[k++]=org[i].r;        }        sort(cut,cut+k);     //   sort(org,org+n,cmp1);        r=1;        for(i=1;i<k;i++)        if(cut[i]!=cut[i-1])        cut[r++]=cut[i];        k=r;        re_root[0].L=0,re_root[0].R=k-1,re_root[0].h=-1;        build_tree(&re_root[0]);        for(i=0;i<n;i++)        {            l=find_num(0,k-1,org[i].l);            r=find_num(0,k-1,org[i].r);            insert(&re_root[0],l,r,org[i].h);        }      printf("%lld\n",find_ans(&re_root[0]));//<<endl;    }    return 0;}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.