Solution - P3509 [POI 2010] ZAB-Frog

卡我空间几个意思

谨以此文祝福 FXY,WQX 百年好合,白头偕老。(不是)(没有)(真没有!)

思路

一道有 DP 标签的倍增水题。

\(m \le 10^{18}\) 思倍增,然后注意到不管在什么时候,从一个点跳到的下一个点都是固定的。于是一个 ST 表干了上去。

然后 MLE 了。

发现我开的 ST 表数组空间干到了 \(400 \text{MB}\) 还多,于是滚动数组。

然后没了。

代码

#include <bits/stdc++.h>
#define rint register int
#define rllong register long long
#define llong long long
#define N 1000006
using namespace std;

llong a[N], to[N], tmp[N], now[N];
llong n, k, m;

int main(){
	scanf("%lld %lld %lld", &n, &k, &m);
	for(rint i = 1; i <= n; ++i)
		scanf("%lld", &a[i]);
	a[n+1] = 2e18+7;
	for(rint i = 1, j = 1; i <= n; ++i){
		while(j < n-k && a[j+k+1]-a[i] < a[i]-a[j]) ++j;
		to[i] = (a[j+k]-a[i] > a[i]-a[j]) ? (j+k) : j;
	}
	for(rint i = 1; i <= n; ++i)
		now[i] = i;
	for( ; m; m>>=1){
		if(m & 1)
			for(rint i = 1; i <= n; ++i) now[i] = to[now[i]];
		for(rint i = 1; i <= n; ++i)
			tmp[i] = to[to[i]];
		for(rint i = 1; i <= n; ++i)
			to[i]  = tmp[i];
	}
	for(rint i = 1; i <= n; ++i)
		printf("%lld ", now[i]);
	return 0;
}

posted @ 2025-04-27 19:18  Hootime  阅读(25)  评论(0)    收藏  举报