社区讨论
19pts,悬4关
P6007[USACO20JAN] Springboards G参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mm33yj7p
- 此快照首次捕获于
- 2026/02/26 14:54 2 周前
- 此快照最后确认于
- 2026/02/27 19:55 2 周前
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int inf=0x7fffffff;
const int N=2e5;
int n,p;
struct node
{
int x,y;
int pos;
int id;
int step;
}num[N+5];
bool cmp1(node xx,node yy)
{
if(xx.x==yy.x)
return xx.y<yy.y;
return xx.x<yy.x;
}
bool cmp2(node xx,node yy){return xx.y<yy.y;}
int jl(int xx1,int yy1,int xx2,int yy2){return abs(xx1-xx2)+abs(yy1-yy2);}
void cdq(int l,int r)
{
if(l==r) return ;
int mid=(l+r)>>1;
cdq(l,mid);
sort(num+l,num+mid+1,cmp2);
sort(num+mid+1,num+r+1,cmp2);
int i=l,j=mid+1;
int minn=inf;
while(j<=r)
{
while(i<=mid && num[i].y<=num[j].y)
{
if(num[j].pos==1 && num[i].pos==2)
minn=min(minn,num[i].step+jl(num[i].x,num[i].y,num[j].x,num[j].y));
if((num[j].pos==2 && num[i].pos==1))
if(num[j].id==num[i].id || num[i].id==-1)
minn=min(minn,num[i].step);
i++;
}
num[j].step=minn;
if(num[j].id==-1) num[j].step=0;
j++;
}
cdq(mid+1,r);
return ;
}
signed main()
{
cin>>n>>p;
for(int i=1;i<=p;i++)
{
int xx1,yy1,xx2,yy2;
cin>>xx1>>yy1>>xx2>>yy2;
num[i*2-1]={xx1,yy1,1,i,inf};
num[i*2]={xx2,yy2,2,i,inf};
}
num[2*p+1]={0,0,2,-1,0};
num[2*p+2]={n,n,1,-2,0};
sort(num+1,num+2*p+3,cmp1);
cdq(1,2*p+2);
cout<<num[2*p+2].step<<"\n";
return 0;
}
可以证明最长的跳跃距离就是最优方案。
所以只需要考虑特殊点(跳板和(0,0),(N,N))。
考虑把跳板分为起点和终点,在保证偏序关系的情况下,每个起点的答案需要从另一个终点转移而来,终点的答案从对应的起点转移而来。发现(0,0)满足终点的性质,(N,N)满足起点的性质。
把这些点都加入同一个序列,跑一个cdq分治。
回复
共 0 条回复,欢迎继续交流。
正在加载回复...