[ABC280G] Do Use Hexagon Grid 2

Problem Statement

A hexagonal cell is represented as (i,j) with two integers i and j.
Cell (i,j) is adjacent to the following six cells:

  • (i1,j1)
  • (i1,j)
  • (i,j1)
  • (i,j+1)
  • (i+1,j)
  • (i+1,j+1)

Let us define the distance between two cells X and Y by the minimum number of moves required to travel from cell X to cell Y by repeatedly moving to an adjacent cell.
For example, the distance between cells (0,0) and (1,1) is 1, and the distance between cells (2,1) and (1,1) is 3.

You are given N cells (X1,Y1),,(XN,YN).
How many ways are there to choose one or more from these N cells so that the distance between any two of the chosen cells is at most D?
Find the count modulo 998244353.

Constraints

  • 1N300
  • 109Xi,Yi109
  • 1D1010
  • (Xi,Yi) are pairwise distinct.
  • All values in the input are integers.

Input

The input is given from Standard Input in the following format:

$N$ $D$
$X_1$ $Y_1$
$\vdots$
$X_N$ $Y_N$

Output

Print the answer.


Sample Input 1

3 1
0 0
0 1
1 0

Sample Output 1

5

There are five possible sets of the chosen cells: {(0,0)},{(0,1)},{(1,0)},{(0,0),(0,1)}, and {(0,0),(1,0)}.


Sample Input 2

9 1
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2

Sample Output 2

33

Sample Input 3

5 10000000000
314159265 358979323
846264338 -327950288
-419716939 937510582
-97494459 -230781640
628620899 862803482
先考虑怎样算出最短路。如果 x1<x2,y1<y2 时,从 (x1,y1)(x2,y2)的方案是先不停的走 (x+1,y+1),使得 x1=x2 或者 y1=y2,然后再慢慢走。所以最短路长度为 max(x2x1,y2y1)x1>x2,y1>y2 时同理,最短路长度不妨写成 max(|x2x1|,|y2y1|)

反之,如果 x1<x2,y1>y2,并不能走 (x+1,y1),所以只能一步一步走。最短路长度为 x2x1+y1y2,最短路为 x1>x2,y1<y2 时同理,最短路长度为 |x2x1+y1y2|

两个结论想办法整合一下,设 a=max(|x2x1|,|y2y1|)b=|x1y1+x2y2|。会发现非常的巧,如果 x1<x2,y1<y2 时,a>b。如果 x1<x2,y1>y2 时, a<b。反过来同理,所以其实两个点 (x1,y1)(x2,y2) 的距离为 max(|x2x1|,|y2y1|,|(x1y1)+(x2y2)|)

然后就非常套路了。枚举 xyxy 的最小值(枚举的是点),并钦定这些点必选。然后看有多少个点在他们围出来的范围内。如果在的话,统计。设有 cnt 个,那么答案会增加 2cnt 个。这样的方案,由于他们的最小值是不同的,所以不会重复统计。不过注意要把 x 相同的, y 相同的, xy相同的强行钦定一个顺序。可以使用离散化处理。

但是如果枚举完暴力去找所有在范围中的数,复杂度 O(n4)。但我们可以使用双指针加入和删除去统计就好了。具体而言,枚举了 x 的最小值和 y 的最小值后,把点按 xy 从小到大加入就行了。

#include<bits/stdc++.h>
using namespace std;
const int N=305,P=998244353;
int n,ans,pw[N],lshx[N],lshy[N],fx[N],fy[N];
long long d;
struct node{
	int x,y;
	bool operator<(const node&n)const{
		return lshx[x]-lshy[y]<lshx[n.x]-lshy[n.y];
	}
}t[N];
int can(int u,int x,int y) 
{
	return t[u].x>=t[x].x&&lshx[t[u].x]<=lshx[t[x].x]+d&&t[u].y>=t[y].y&&lshy[t[u].y]<=lshy[t[y].y]+d;
}
int main()
{
	scanf("%d%lld",&n,&d);
	for(int i=pw[0]=1;i<=n;i++)
		pw[i]=pw[i-1]*2%P;
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&t[i].x,&t[i].y);
		lshx[i]=t[i].x,lshy[i]=t[i].y;
	}
	sort(lshx+1,lshx+n+1);
	sort(lshy+1,lshy+n+1);
	for(int i=1;i<=n;i++)
	{
		t[i].x=lower_bound(lshx+1,lshx+n+1,t[i].x)-lshx;
		fx[t[i].x]++,t[i].x+=fx[t[i].x]-1;
		t[i].y=lower_bound(lshy+1,lshy+n+1,t[i].y)-lshy;
		fy[t[i].y]++,t[i].y+=fy[t[i].y]-1;
	}
	sort(t+1,t+n+1);
//	for(int i=1;i<=n;i++)
//		printf("%d %d\n",t[i].x,t[i].y);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(!can(j,i,j)||!can(i,i,j))
				continue;
			int r=0,s=0;
			for(int k=1;k<=n;k++)
			{
				if(!can(k,i,j))
					continue;
				int z=lshx[t[k].x]-lshy[t[k].y];
				while(r<n)
				{
					if(!can(r+1,i,j)) 
						++r;
					else if(lshx[t[r+1].x]-lshy[t[r+1].y]<=z+d)
						++r,++s;
					else
						break;
				}
				if(k<=i&&k<=j&&z+d>=lshx[t[i].x]-lshy[t[i].y]&&z+d>=lshx[t[j].x]-lshy[t[j].y])
				{
					int t=s;
					if(i==j&&j==k)
						t--;
					else if(i==j||j==k||i==k)
						t-=2;
					else
						t-=3;
					(ans+=pw[t])%=P;
//					printf("%d %d %d %d %d\n",i,j,k,ans,t);
				}
				--s;
			}
		}
	}
	printf("%d",ans) ;
}
posted @   灰鲭鲨  阅读(60)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示