[ABC280G] Do Use Hexagon Grid 2
Problem Statement
A hexagonal cell is represented as with two integers and .
Cell is adjacent to the following six cells:
Let us define the distance between two cells and by the minimum number of moves required to travel from cell to cell by repeatedly moving to an adjacent cell.
For example, the distance between cells and is , and the distance between cells and is .
You are given cells .
How many ways are there to choose one or more from these cells so that the distance between any two of the chosen cells is at most ?
Find the count modulo .
Constraints
- 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: , and .
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
反之,如果 ,并不能走 ,所以只能一步一步走。最短路长度为 ,最短路为 时同理,最短路长度为 。
两个结论想办法整合一下,设 ,。会发现非常的巧,如果 时,。如果 时, 。反过来同理,所以其实两个点 和 的距离为
然后就非常套路了。枚举 ,, 的最小值(枚举的是点),并钦定这些点必选。然后看有多少个点在他们围出来的范围内。如果在的话,统计。设有 个,那么答案会增加 个。这样的方案,由于他们的最小值是不同的,所以不会重复统计。不过注意要把 相同的, 相同的, 相同的强行钦定一个顺序。可以使用离散化处理。
但是如果枚举完暴力去找所有在范围中的数,复杂度 。但我们可以使用双指针加入和删除去统计就好了。具体而言,枚举了 的最小值和 的最小值后,把点按 从小到大加入就行了。
#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) ;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!