Hiho the 124th week #1421: four fork Tree "two-dimensional line segment tree"

Source: Internet
Author: User
Tags min time limit

#1421: Four fork tree time limit: 20000ms single point limit: 2000ms memory limit: 256MB description

Little ho: Next weekend we're going to play in the next city.

Small hi: Anyway, very close to the back, good ah.

Little ho: Well, let me start by planning the route.

Little Ho opened the map app in the phone and moved the coordinates to the city next door. A variety of shops are displayed on the street map.

Little hi: Little ho, do you know how the map app calculates the shops around you?

Little ho: Hey. Didn't think about it.

Little hi: Actually this is also a very interesting question. Let's first simplify the model, assuming there is a plan with n points distributed above, and the coordinates of the point I are (X[i],y[i]).

Little ho: Use points to represent shops.

Little hi: Yes, and if we are in the coordinates of (a A, A, b), then we have a radius of R in the range (including the edge), how many points?

Little ho: It feels like a very interesting question, let me think about it.

Tip: Four fork tree (quadtree) input

Line 1th: 2 integer n,m. 1≤n≤50,000,0≤m≤5,000.

2nd.. N+1 line: 2 integers per line x, Y, line i+1 represents the coordinates of the point I, guaranteed no duplicate points. 0≤x,y≤30,000

Line n+2..n+m+1:3 integer a,b,r per line, indicating the center coordinate (a, b) of the query, and radius R. 0≤a,b,r≤30,000 Output

1th.. M-line: 1 integers per line, and line I indicates the number of points in the center of the (x, y) query. Sample input

2 2
1 1
2 2
2 2 1
2 2 2
Sample output
1
2
tip: Four fork tree (quadtree)

Little ho: The simple idea is that I use a two-dimensional array to represent the entire floor plan. Assuming the range of coordinates is L, a l*l array is required.

For (A, B) and R, I check the b-r column to the B+r column of the a-r to the A+r row to see if there is a bit, and the point to (A, b) is less than or equal to R.

For L more than 10000 of the situation there is no way to achieve.

Little hi: Yes, in the case of large coordinate ranges and points, there is a real problem.

Little ho: I was wondering if I could divide the whole area into small areas, each time in a small area nearby to find the nearest point.

Little hi: Little ho You have a great idea, and we might as well try it.

Little ho: How should that be divided?

Little hi: Do you remember the line tree? In the processing of the segment tree, we divide an interval from one point into two segments. Here we also use the same method to divide a region into 4 pieces:

From top to bottom, from left to right, labeled 1234 respectively.

We put all the points into these areas, in order to make an area in the number of points not too much, we set an area of the number of points limit.

If there are too many points in an area, we will take this area four points and put the new point in the sub-region.

Little ho: Sounds like a lot of sense.

Little hi: Of course it makes sense that this data structure is called "Quadtree (Quadtree)". Each of its basic units is:

Quadtreenode:
	const node_capacity;//Each node contains a limit of the number of points, a constant
	boundary;//The range of the node, which contains 4 parameters, the upper and lower left and right border of the region
	points; A list of nodes within the region
	Childnode;//contains 4 parameters representing 4 sub-regions

Assuming Node_capacity=1, then we can divide the entire region into:

Little ho: Well, I understand that, because it is similar to a line tree, then there is the same insert and query operation.

Little hi: Yes.

Quadtree insert operation: When inserting a new node (x, y), if it is not in the current region, exit, otherwise add it to the node list of the zone points, if the node list for the current region is full. Then the area is four points, and the node is added to the sub-region.

Insert (Quadtreenode Nownode, point P):
	if (p not in nownode.boundary) then
		Return 
	End if
	if ( NowNode.points.length < node_capacity)
		then NowNode.points.append (p)
	Else
		nownode.divide ()//area four min. For each
		Childnode of Nownode
			inserts (Childnode, p)
		end for
	end If

A quad-tree query operation is typically a range of points, so the parameters that are brought in are also an area range:

Query (Quadtreenode nownode, Range):
	If (Quadtreenode.boundary does not intersect range) then
		//The region of the node does not intersect the query area C2/>return empty
	End if for each
	p in nownode.points
		if (p in range) and then
			Pointsinrange.append (p)
		End
	for the If
	(nownode.isdivide)
		then//If the zone has been partitioned, then the nodes in the sub-zone may also be in
		the for each childnode of Nownode
			Query (childnode, range)
		end for
	end If
	Return Pointsinrange

In our question, we can use a circle of external squares as an area to find a list of points, and then check whether it is within the circle.

Little ho: So it does look like the search is less quantitative.

Little hi: Yes, and the process of dynamically building a four-fork tree reduces the overhead of space.

Little ho: Well, let me try it out for a second.


Embarrassed-.-at the insertion point, fascinated, fascinated---whining-.-



Code:

#include <cstdio> #include <cstring> #include <algorithm> using namespace std;
int xx[60000],yy[60000];
    struct node{bool Fafe;
    int length,hao[5],x[2],y[2];
node * clidren[4];
}PP[1000000];
    void Lon (node *x) {x->length=0;
x->fafe=false;
} int a,b,r,ans,lp,ll; void pan (int i)//determine if in circle {if ((A-xx[i]) * (A-xx[i]) + (B-yy[i]) * (B-yy[i]) <=r*r) ans++; void Add (int ii,node
* x);
    void Fen (node * x) {int mx= (x->x[0]+x->x[1]) >>1;
    int my= (x->y[0]+x->y[1]) >>1; for (int i=0;i<4;i++) x->clidren[i]=&pp[lp++];//is divided into four x->clidren[0]->x[0]=x->x[0];x->clid
    ren[0]->x[1]=mx;
    x->clidren[0]->y[0]=x->y[0];x->clidren[0]->y[1]=my;
    x->clidren[1]->x[0]=mx+1;x->clidren[1]->x[1]=x->x[1];
    x->clidren[1]->y[0]=x->y[0];x->clidren[1]->y[1]=my;
    x->clidren[2]->x[0]=x->x[0];x->clidren[2]->x[1]=mx; x->clidren[2]->y[0]=my+1;x->clidren[2]->y[1]=x->y[1];
    x->clidren[3]->x[0]=mx+1;x->clidren[3]->x[1]=x->x[1];
    x->clidren[3]->y[0]=my+1;x->clidren[3]->y[1]=x->y[1];
    Yes for (int i=0;i<4;i++) lon (X->clidren[i]);
        Yes for (int j=0;j< x->length; j + +) {int ii=x->hao[j]; for (int i=0;i<4;i++) {if (x->clidren[i]->x[0]<=xx[ii]&&x->clidren[i]->x[1]
                >=xx[ii]&&x->clidren[i]->y[0]<=yy[ii]&&x->clidren[i]->y[1]>=yy[ii]) {
                Add (Ii,x->clidren[i]);
            Break
    }}}//Yes x->fafe=true;
    x->length=0;
        yes} void Add (int ii,node * x)//insertion point {if (!x->fafe) {x->hao[x->length++]=ii;
        if (x->length>ll) {fen (x); }} else {for (int i=0;i<4;i++) {if (x->clidren[i]->x[0]<=xx[ii]&&x->clidren[i]->x[1]>=xx[ii]&&x->clidren[i]- 
                &GT;Y[0]&LT;=YY[II]&AMP;&AMP;X-&GT;CLIDREN[I]-&GT;Y[1]&GT;=YY[II]) {Add (Ii,x->clidren[i]);
                /*x->clidren[i]->hao[x->clidren[i]->length++]=ii;--was wrong at first---this area may have been divided-.-
                if (x->clidren[i]->length>ll) {fen (x->clidren[i]);
            }*/break; }}}} void query (node * x,int l,int r,int xi,int s)//Find {if (!x->fafe) {if (x->lengt
        h) {for (int i=0;i<x->length;i++) pan (X->hao[i]);
    } return; } for (int i=0;i<4;i++) {if (l>=x->clidren[i]->x[0]&&r<=x->clidren[i]->x[1]& AMP;&AMP;XI&GT;=X-&GT;CLIDREN[I]-&GT;Y[0]&AMP;&AMP;S&LT;=X-&GT;CLIDREN[I]-&GT;Y[1]) {query (x->clid REn[i],l,r,xi,s);
        return;
        }} if (L>=x->clidren[1]->x[0]) {query (x->clidren[1],l,r,xi,x->clidren[1]->y[1]);
    Query (x->clidren[3],l,r,x->clidren[3]->y[0],s);
        } else if (R<=x->clidren[0]->x[1]) {query (x->clidren[0],l,r,xi,x->clidren[0]->y[1]);
    Query (x->clidren[2],l,r,x->clidren[2]->y[0],s);
        } else if (Xi>=x->clidren[2]->y[0]) {query (x->clidren[2],l,x->clidren[2]->x[1],xi,s);
    Query (x->clidren[3],x->clidren[3]->x[0],r,xi,s);
        } else if (S<=x->clidren[0]->y[1]) {query (x->clidren[0],l,x->clidren[0]->x[1],xi,s);
    Query (x->clidren[1],x->clidren[1]->x[0],r,xi,s);
        } else {query (x->clidren[0],l,x->clidren[0]->x[1],xi,x->clidren[0]->y[1]); Query (X->clidren[1],x->clidren[1]->x[0],r,xi,x->clidren[1]->y[1]);
        Query (x->clidren[2],l,x->clidren[2]->x[1],x->clidren[2]->y[0],s);
    Query (x->clidren[3],x->clidren[3]->x[0],r,x->clidren[3]->y[0],s);
    }} int main () {int n,m;
    scanf ("%d%d", &n,&m);
    pp[0].x[0]=0;pp[0].x[1]=30000;
    pp[0].y[0]=0;pp[0].y[1]=30000;
    Lon (&pp[0]); lp=1;
    ll=4;
        for (int i=0;i<n;i++) {scanf ("%d%d", &xx[i],&yy[i]);
    Add (i,&pp[0]);
        } for (int i=0;i<m;i++) {scanf ("%d%d%d", &a,&b,&r);
        ans=0;
        Query (&pp[0],max (0,a-r), Min (30000,a+r), Max (0,b-r), Min (30000,b+r));
    printf ("%d\n", ans);
} return 0;
 }/* 2 3 0 1 */


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.