Problem Description
General Zhang recently got a plasma shield to intercept incoming missiles.
The shape of the plasma shield is basically a square with a horizontal diagonal. Due to some technology issues, the plasma shield cannot protect the whole square area. One vertical stripe in the middle of the square is penetrable to the missiles. So, in fact the shield is formed by two identical isosceles right triangle. Missiles hitting the surface or the edge of the shield are considered intercepted.
Now N missiles are coming to General Zhang’s army. The i−th missile will strike the position (xi,yi) . Because he only has one plasma shield, he want to calculate when the shield is turned on in a particular way, how many of the missiles it can stop.
General Zhang will give you M queries, each query describe the shape of a plasma by 4 integers (X,Y,D,W) . (X,Y) denotes the center of the shield. D denotes the length of the diagonal. W denotes the width of the unprotected stripe. For each query, you need to output number of the missiles stopped by the shield.
The shape of the plasma shield is basically a square with a horizontal diagonal. Due to some technology issues, the plasma shield cannot protect the whole square area. One vertical stripe in the middle of the square is penetrable to the missiles. So, in fact the shield is formed by two identical isosceles right triangle. Missiles hitting the surface or the edge of the shield are considered intercepted.
![](https://i-blog.csdnimg.cn/blog_migrate/83f17b202af7255b89382dd2ccf708c7.jpeg)
Now N missiles are coming to General Zhang’s army. The i−th missile will strike the position (xi,yi) . Because he only has one plasma shield, he want to calculate when the shield is turned on in a particular way, how many of the missiles it can stop.
General Zhang will give you M queries, each query describe the shape of a plasma by 4 integers (X,Y,D,W) . (X,Y) denotes the center of the shield. D denotes the length of the diagonal. W denotes the width of the unprotected stripe. For each query, you need to output number of the missiles stopped by the shield.
Input
The first line of input contains an integer
T
(
T≤20
), which represents the number of test cases.
Each test case starts with N and M ( 1≤N,M≤20000 ) in a line. The i−th line of the next N lines contains two integers xi and yi . The next M lines each line has 4 integers X,Y,D,W , which represents a query. D and W are guaranteed to be even numbers.
Each test case starts with N and M ( 1≤N,M≤20000 ) in a line. The i−th line of the next N lines contains two integers xi and yi . The next M lines each line has 4 integers X,Y,D,W , which represents a query. D and W are guaranteed to be even numbers.
Output
For each test case, output a single line consisting of “
Case #X:” first.
X
is the test case number starting from 1. For each query, output the number of missiles that are intercepted in a single line. Do not output extra spaces or newlines.
Sample Input
1 4 3 -5 0 -4 0 -3 0 0 0 0 0 0 0 0 0 8 0 0 0 8 2
Sample Output
Case #1: 1 3 2
Source
写了个kdtree。。似乎复杂度多了两个log,hdu上并不能跑过去
如果谁的kdtree跑过去的话求告诉一下。。或者谁有数据求发一份。。我在本机测测到底跑了多久
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
大概就是把每个点转换成(x,x+y,x-y)这三个维度用kdtree维护
每个三角形都可以用这三个维度限定出来
直接用kdtree维护即可
复杂度是T*Mlog^3N。标算似乎只有一个log
先把代码贴出来吧
#include<cstdio>
#include<algorithm>
using namespace std;
struct point
{
int p[3],y;
int min[3],max[3];
int ll,rr;
int s;
}tr[50001];
int cmpd;
inline bool cmp(point x,point y)
{
return x.p[cmpd]<y.p[cmpd];
}
inline void up(int p)
{
int L=tr[p].ll,R=tr[p].rr;
tr[p].min[0]=min(tr[p].min[0],tr[L].min[0]);
tr[p].min[0]=min(tr[p].min[0],tr[R].min[0]);
tr[p].min[1]=min(tr[p].min[1],tr[L].min[1]);
tr[p].min[1]=min(tr[p].min[1],tr[R].min[1]);
tr[p].min[2]=min(tr[p].min[2],tr[L].min[2]);
tr[p].min[2]=min(tr[p].min[2],tr[R].min[2]);
tr[p].max[0]=max(tr[p].max[0],tr[L].max[0]);
tr[p].max[0]=max(tr[p].max[0],tr[R].max[0]);
tr[p].max[1]=max(tr[p].max[1],tr[L].max[1]);
tr[p].max[1]=max(tr[p].max[1],tr[R].max[1]);
tr[p].max[2]=max(tr[p].max[2],tr[L].max[2]);
tr[p].max[2]=max(tr[p].max[2],tr[R].max[2]);
tr[p].s=tr[L].s+tr[R].s+1;
}
inline int build(int l,int r,int d)
{
int mid=(l+r)/2;
cmpd=d;
nth_element(tr+l,tr+mid,tr+r+1,cmp);
tr[mid].min[0]=tr[mid].p[0];
tr[mid].min[1]=tr[mid].p[1];
tr[mid].min[2]=tr[mid].p[2];
tr[mid].max[0]=tr[mid].p[0];
tr[mid].max[1]=tr[mid].p[1];
tr[mid].max[2]=tr[mid].p[2];
tr[mid].s=1;
tr[mid].ll=0;
tr[mid].rr=0;
if(l<mid)
tr[mid].ll=build(l,mid-1,(d+1)%3);
if(r>mid)
tr[mid].rr=build(mid+1,r,(d+1)%3);
up(mid);
return mid;
}
inline int ask(int p,int x10,int x11,int x12,int x20,int x21,int x22,int d)
{
if(p==0)
return 0;
int x1[3],x2[3];
x1[0]=x10;
x1[1]=x11;
x1[2]=x12;
x2[0]=x20;
x2[1]=x21;
x2[2]=x22;
if(x1[0]>tr[p].max[0]||x1[1]>tr[p].max[1]||x1[2]>tr[p].max[2]||x2[0]<tr[p].min[0]||x2[1]<tr[p].min[1]||x2[2]<tr[p].min[2])
return 0;
if(x1[0]<=tr[p].min[0]&&tr[p].max[0]<=x2[0]&&x1[1]<=tr[p].min[1]&&tr[p].max[1]<=x2[1]&&x1[2]<=tr[p].min[2]&&tr[p].max[2]<=x2[2])
return tr[p].s;
int ans=0;
if(x1[0]<=tr[p].p[0]&&tr[p].p[0]<=x2[0]&&x1[1]<=tr[p].p[1]&&tr[p].p[1]<=x2[1]&&x1[2]<=tr[p].p[2]&&tr[p].p[2]<=x2[2])
ans++;
if(x1[d]<=tr[p].p[d])
ans+=ask(tr[p].ll,x10,x11,x12,x20,x21,x22,(d+1)%3);
if(x2[d]>tr[p].p[d])
ans+=ask(tr[p].rr,x10,x11,x12,x20,x21,x22,(d+1)%3);
return ans;
}
int main()
{
int T,k=0;
scanf("%d",&T);
while(T>0)
{
T--;
k++;
int n,m;
scanf("%d%d",&n,&m);
int i;
for(i=1;i<=n;i++)
{
scanf("%d%d",&tr[i].p[0],&tr[i].y);
tr[i].p[1]=tr[i].p[0]+tr[i].y;
tr[i].p[2]=tr[i].p[0]-tr[i].y;
}
int rt=build(1,n,0);
printf("Case #%d:\n",k);
int x,y,d,w;
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x,&y,&d,&w);
int len=d/2;
int x11=x-len,x12=y;
int x21=x-w/2,x22=y+len-w/2;
int x31=x+w/2,x32=y+len-w/2;
int x41=x-w/2,x42=y-len+w/2;
int x51=x+w/2,x52=y-len+w/2;
int x61=x+len,x62=y;
//printf("%d %d %d %d %d %d %d %d %d %d %d %d\n",x11,x12,x21,x22,x31,x32,x41,x42,x51,x52,x61,x62);
//printf("%d %d %d %d %d %d\n",x11,x41+x42,x21-x22,x21,x21+x22,x41-x42);
if(w!=0)
printf("%d\n",ask(rt,x11,x41+x42,x21-x22,x21,x21+x22,x41-x42,0)+ask(rt,x31,x51+x52,x31-x32,x61,x31+x32,x51-x52,0));
else
printf("%d\n",ask(rt,x11,x41+x42,x21-x22,x61,x21+x22,x41-x42,0));
}
}
return 0;
}