标签:while c++ else ref mes lan r++ main ++
https://www.luogu.com.cn/problem/P3509
数轴上有n个点,有一个青蛙在这些点上跳;
规则是每次向距当前点第k小的点跳,如果有相同距离则向下标较小的跳;
求从每个点出发跳了m次后在哪里;
\(n\leq 10^5 ,m\leq 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;
}
标签:while c++ else ref mes lan r++ main ++
原文地址:https://www.cnblogs.com/wsfwsf/p/14068028.html