Luogu P3509 [POI2010]ZAB-Frog
Posted wsfwsf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P3509 [POI2010]ZAB-Frog相关的知识,希望对你有一定的参考价值。
https://www.luogu.com.cn/problem/P3509
题面
数轴上有n个点,有一个青蛙在这些点上跳;
规则是每次向距当前点第k小的点跳,如果有相同距离则向下标较小的跳;
求从每个点出发跳了m次后在哪里;
(nleq 10^5 ,mleq 10^{18})
分析
显然倍增,考虑如何求出距当前点距离(K)小点
显然距离前K小点的点集在数轴上是连续的且单调增
所以用单调队列维护
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1e5+5;
int n,k;
ll m,a[N];
int f[N][60];
int main() {
scanf("%d%d%lld",&n,&k,&m);
for(int i=1;i<=n;i++) {
scanf("%lld",&a[i]);
}
int l=1,r=k+1;
f[1][0]=r;
for(int i=2;i<=n;i++) {
while(r<n&&a[i]-a[l]>a[r+1]-a[i]) r++,l++;
if(a[i]-a[l]>=a[r]-a[i]) f[i][0]=l;
else f[i][0]=r;
}
for(int j=1;j<60;j++) {
for(int i=1;i<=n;i++) {
f[i][j]=f[f[i][j-1]][j-1];
}
}
for(int i=1;i<=n;i++) {
int now=i; ll res=m;
for(int j=59;j>=0;j--) {
if(res>=(1LL<<j)) {
res-=(1LL<<j);
now=f[now][j];
}
}
printf("%d ",now);
}
return 0;
}
以上是关于Luogu P3509 [POI2010]ZAB-Frog的主要内容,如果未能解决你的问题,请参考以下文章
luogu P3512 [POI2010]PIL-Pilots
[luogu3505][bzoj2088][POI2010]TEL-Teleportation