简体   繁体   中英

Find the number of points on or inside a triangle for very large number of points?

You are given N lattice points (Xi, Yi), i = 1, 2, ..., N on a 2D Coordinate System. You have to process Q queries, each query will be given as the form "xyd". Let ABC be the triangle having vertices at A(x+d, y), B(x, y) and C(x, y+d). For each query, you have to find how many of the given lattice points lie inside or on the boundary of the triangle ABC. Input

The first line of the input contains two space-sparated integers N and Q. Each of the following N lines have two space-sparated integers Xi, Yi giving the x and y coordinate of a lattice point. Then the following Q lines contain three space-sparated integers x, y, d giving a query. Output

For each query, output one integer on a line which denotes the number of the given lattice points which lie inside or on the boundary of the triangle. Constraints

1 ≤ N ≤ 300000 (3 * 105)
1 ≤ Q ≤ 200000 (2 * 105)
1 ≤ Xi, Yi ≤ 300000 (3 * 105)
1 ≤ x, y, d ≤ 300000 (3 * 105)

Sample

Input 1: 
5 3  
1 3  
1 5  
3 6  
4 4  
2 6
1 5 3    
1 5 4
1 1 1

Output 1:
3
3
0

Input 2:
2 2
1 5
3 7
2 5 6
2 3 4

Output 2:
1
0

#include<iostream>
#include<cstdio>
#include<cstdlib>

using namespace std;

int sizer[300000]={0};//sizer[i] tells the number of points having i as the abscissa

int cmp(const void *a,const void *b)
{
    return *(int *)a-*(int *)b;
}

int main()
{
    int **X=(int **)malloc(300000*sizeof(int));//each pointer points to an array of ints
    for(int i=0;i<300000;i++)
    X[i]=NULL;
    int N,Q;
    int x,y,d;
    scanf("%d %d",&N,&Q);
    scanf("%d %d",&x,&y);
    sizer[x-1]++;
    for(int i=1;i<=N;i++)
    {
        scanf("%d %d",&x,&y);
        sizer[x-1]++;
        X[x-1]=(int *)realloc(X[x-1],sizer[x-1]*sizeof(int));
        X[x-1][sizer[x-1]-1]=y;}
        for(int i=0;i<300000;i++)
        {
         if(X[i]!=NULL)
         qsort(X[i],sizer[i],sizeof(int),cmp);}//sorts all the ordinates

         for(int i=1;i<=Q;i++)//query loop
         {
          scanf("%d %d %d",&x,&y,&d);
          int count=0;
          for(int j=x;j<=x+d;j++)//this loop works for each row from x to x+d
          {
           if(X[j-1]==NULL)//no points on X=j line
              continue;
           else if(X[j-1][sizer[j-1]-1]<y)//the largest ordinate point on X=j line is <y ie                below the triangle
              continue;
           else if(X[j-1][0]+j>x+y+d)//the smallest ordinate point on X=j line is above the triangle
               continue;  
         int k=0;
        for(;X[j-1][k]<y&&k<sizer[j-1];k++);//k is the position from where counting of points begins.moving along the X=j line and counting the points
        int v=k;
        for(;X[j-1][v]+j<=x+y+d&&v<sizer[j-1];v++);
        count=count+v-k;}
        printf("%d\n",count);}
        return 0;}

I get a SIGSEGV on an online judge when the input case is very large but works all right on small test cases. Where am I going wrong?

Check the first line of the main function:

int **X=(int **)malloc(300000*sizeof(int));

Here, you are dynamically allocation a two-dimensional array X. Now, see the following constraint:

N ≤ 300000 (3 * 10^5)

So, your program will allocate X[3 *10^5][3 *10^5] ie. 9*10^10 array of integers. Array of this size is too large to fit in memory. In any programming languages, such a large memory can't be allocated/allowed.

Refer the following Link

A SIGSEGV is an error(signal) caused by an invalid memory reference or a segmentation fault. You are probably trying to access an array element out of bounds or trying to use too much memory.

So, your program generated SIGSEGV due to too much memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM