Chessforces is coming into a great war. The Knights Alliance is aiming to attack the Bishops Alliance land, it is up to you to help bishops defending their homeland.
In order to defeat the attacking knights, bishops want to make their defense line as big as possible. Defense line is a set of bishops on the chessboard where each pair of bishops in this set satisfies OK relation. OK relation between bishop i and bishop j is satisfied if they are on the same diagonal and the number of squares on the diagonal path between i and j is at least equal to pi2 + pj2 + C, where pk is privacy distance for bishop k and it is given for each bishop on the board, C is a given constant. Note that the path between two bishops includes both bishops squares.
Given the coordinates of each bishop on the chessboard, help them to find the defense line with maximum number of bishops.
First line contains number of test cases T. Each test case contains one line with (0 < n ≤ 105) size of the chessboard edge, (0 < m ≤ 105) number of bishops and the constant (0 ≤ C ≤ 105) then m line follows, the ith line of them contains three integers: (1 ≤ ri, ci, pi ≤ n) where (ri,ci) is row number and column number of the ith bishop and pi is the privacy of the ith bishop.
Print a single integer, the size of the defense line with maximum number of bishops.
1 8 5 2 7 7 1 4 4 1 3 5 1 2 6 2 4 8 1
2
Large I/O files. Please consider using fast input/output methods.
First test case explanation, columns go from left to right and rows go up to bottom, bishops labeled with borders are included in the defense line.

先把每一对角线上的点都记录下来,然后可以把每个点看为一个线段区间,这个区间的范围也就是[ xi- ( pi*pi+c/2+0.5 ) , xi + ( pi*pi+c/2+0.5 ) ] 这样只要两个区间不相交,就可以保证满足“OK relation”
然后就是对于每条对角线贪心求最大不相交区间覆盖
调了半天看了题解才知道要“
并且大牛们用的区间都是[ xi- ( pi*pi) , xi + ( pi*pi) ] 因为那些项都是常数,可以在贪心时判断条件稍微改一下
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<functional>
#include<vector>
using namespace std;
struct node
{
int x;
double p;
};
double c;
int cmp(node a,node b)
{
double s1=a.p+c/2-0.5,s2=b.p+c/2-0.5;
if(1.0*a.x-s1==1.0*b.x-s2)
return a.x+s1<b.x+s2;
return 1.0*a.x-s1<1.0*b.x-s2;
}
vector<node>w[200005],v[200005];
int main()
{
freopen("bishops.in","r",stdin);
int T,t,n,m,i,ans,j,x,y;
double p;
node point;
scanf("%d",&T);
while(T--)
{
ans=0;
scanf("%d %d %lf",&n,&m,&c);
for(i=0;i<=2*n+1;i++)
{
w[i].clear();
v[i].clear();
}
for(i=0;i<m;i++)
{
scanf("%d %d %lf",&x,&y,&p);
p*=p;
point.x=x;
point.p=p;
w[x-y+n].push_back(point);
v[x+y-1].push_back(point);
}
for(i=0;i<=2*n;i++)
{
sort(w[i].begin(),w[i].end(),cmp);
int t=0;
node po;
double ri;
for(j=0;j<w[i].size();j++)
{
po=w[i][j];
double s=po.p+c*1.0/2-0.5;
if(j==0)
{
t=1;
ri=po.x+s;
continue;
}
if(ri<=1.0*po.x-s)
{
t++;
ri=po.x+s;
}
else
{
ri=min(ri,po.x+s);
}
}
ans=max(ans,t);
}
//其实完全可以用三维vector嵌套一层循环,代码比较简练
for(i=0;i<=2*n;i++)
{
sort(v[i].begin(),v[i].end(),cmp);
int t=0;
node po;
double ri;
for(j=0;j<v[i].size();j++)
{
po=v[i][j];
double s=po.p+c*1.0/2-0.5;
if(j==0)
{
t=1;
ri=po.x+s;
continue;
}
if(ri<=1.0*po.x-s)
{
t++;
ri=po.x+s;
}
else
{
ri=min(ri,po.x+s);
}
}
ans=max(ans,t);
}
printf("%d\n",ans);
}
return 0;
}