洛谷 P6010 - [USACO20JAN] Falling Portals P

先考虑怎么对一组询问求解答案。容易想到一种贪心策略:如果 aqi<ai,那么我们肯定希望自己能够尽量快地下落,因此如果遇到一个下落速度大于当前世界下落速度的传送门我们肯定就会进那个世界,如此走下去知道能够传送到世界 qi 为止。对于 aqi>ai 的情况也类似,只不过要下落速度越慢越好。

考虑处理前一种情况,后一种情况则是镜像的。我们将 aj>ai 的部分插入直线凸包,那么从 i 开始经过的世界就是插入 i 这条直线时,i 这条直线右边的部分,维护出直线凸包以后相当于我们要找到直线凸包上与 y=aqiqix 有交的那一段,可以在凸包上二分即可,这样时间可以使用追及问题的方法求出。

时间复杂度 O(nlogn)

const int MAXN=2e5;
int n,a[MAXN+5],q[MAXN+5],ord[MAXN+5],ans1[MAXN+5],ans2[MAXN+5],stk[MAXN+5],tp;
bool check(int x,int y,int k){return 1ll*(a[x]-a[k])*(y-k)<1ll*(a[y]-a[k])*(x-k);}
void ins(int x,int flg){
while((tp&&((stk[tp]<x)^flg))||(tp>1&&check(stk[tp-1],stk[tp],x)))--tp;
stk[++tp]=x;
if((a[q[x]]<a[x])^flg){
if(flg^(q[x]>stk[1]))return;int l=2,r=tp,p=1;
while(l<=r){
int mid=l+r>>1;
if((flg^(q[x]<stk[mid]))&&check(stk[mid],stk[mid-1],q[x]))p=mid,l=mid+1;
else r=mid-1;
}
ans1[x]=abs(a[stk[p]]-a[q[x]]);ans2[x]=abs(stk[p]-q[x]);
int d=__gcd(ans1[x],ans2[x]);ans1[x]/=d;ans2[x]/=d;
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)scanf("%d",&q[i]);
for(int i=1;i<=n;i++)ord[i]=i;
sort(ord+1,ord+n+1,[&](int x,int y){return a[x]>a[y];});
for(int i=1;i<=n;i++)ins(ord[i],0);tp=0;
for(int i=n;i;i--)ins(ord[i],1);
for(int i=1;i<=n;i++){
if(!ans1[i])puts("-1");
else printf("%d/%d\n",ans1[i],ans2[i]);
}
return 0;
}
posted @   tzc_wk  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
历史上的今天:
2022-08-07 UOJ #750. -【UNR #6】小火车(meet-in-the-middle+抽屉原理)
2022-08-07 UOJ #751 -【UNR #6】神隐(交互题)
点击右上角即可分享
微信分享提示