题解:P17833 [CSP-S 2026] 迁徙
lailai0916 · · 题解
解题思路
记
最短路严格递增,起点右侧各层按坐标分离。两路若至少两层不同,逐层取最大、最小路径再由大转小拼接,可得第三路;同层两点不相邻时,夹点也产生第三路。故恰好两路仅有单个相邻菱形:
记
其中
固定
右延伸要求
两侧边界被强制后,路径最短且仅在菱形处分叉,左右独立,答案为:
利用
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=2000005;
ll x[N];
int l[N],f[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int c,T;
cin>>c>>T;
while(T--)
{
int n;
ll d;
cin>>n>>d;
for(int i=1;i<=n;i++)cin>>x[i];
int j=0;
for(int i=1;i<=n;i++)
{
while(j<n&&x[j+1]-x[i]<=d)
{
j++;
l[j]=i;
}
f[i]=1+(j>i?l[i+1]:i)-l[i];
if(f[i]>1)f[i]+=f[l[i]]-1;
}
l[n+1]=n+1;
ll ans=0;
for(int i=n;i>=1;i--)
{
int k=j;
while(l[j]==i)j--;
f[i]=1+k-max(i,j);
if(f[i]>1)f[i]+=f[k]-1;
int a=l[i];
if(a<i-1)ans+=1ll*(l[a+1]==l[a]?f[a+1]-1:l[a+2]-l[a+1])*(l[i+1]>a+1?f[i]:1);
}
cout<<ans<<'\n';
}
return 0;
}