Luogu P3403 跳楼机|同余最短路

题意:给出跳楼机的4个操作,分别为
1.向上移动(x)层;

2.向上移动(y)层;

3.向上移动(z)层;

4.回到第一层。 显然,并不需要

求从第一层开始,能到达(1)(h)中的多少层?

(1<=h<=2^{63}-1)

(1<=x, y, z<=100000)

题解:

好像可以直接(DP)?

布星啊,看下数据范围。

那先来推推定理?

接下来假设(xle yle z)

对于一个数(k),若它能到达,则(k+x,k+2x,k+...)(均(le h))均能到达,(y)(z)同理

那我们可以选(x)为模数,若(k)可以,上面的都可以!显然可以设(f[i])表示最小的可以用(y,z)表示出来的数。计算答案只需求(sumlimits^{x-1}_{i=0}(h-f[i])/x+1),空间是质的飞跃

等等,你这根本不是递推啊,dp个鬼啊。

好吧,确实不行,但看下转移?

(f[i+y]=f[i]+y,f[i+z]=f[i]+z)

似曾相识有没有?

这与最短路非常相像完 全 一 致!

那就用最短路代替,从(i->(i+y)\%x)边权(y),从(i->(i+z)\%x)边权(z)

自此,算法成型。

这就是同余系最短路

tips:应从(1\%x)开始跑最短路!

#include<bits/stdc++.h>
using namespace std;
long long cc,to[300100],net[300100],fr[300100],l[300100],g;
long long ans,hh,f[300100],h[300100],ha[300100],x[4];
bool vis[300100];
void addedge(long long u,long long v,long long len)
{
	cc++;
	to[cc]=v;net[cc]=fr[u];fr[u]=cc;l[cc]=len;
}
void add(long long x,long long y)
{
	g++;
	h[g]=x;ha[g]=y;
	long long fa=g/2,so=g;
	while (h[fa]>h[so]&&fa)
	{
		swap(h[fa],h[so]);
		swap(ha[fa],ha[so]);
		so=fa;fa/=2;
	}
}
long long del()
{
	long long re=ha[1];
	h[1]=h[g];ha[1]=ha[g];g--;
	long long fa=1,so=2;
	if (h[so]>h[so+1]&&so+1<=g) so++;
	while (h[fa]>h[so]&&so<=g)
	{
		swap(h[fa],h[so]);
		swap(ha[fa],ha[so]);
		fa=so;so*=2;
		if (h[so]>h[so+1]&&so+1<=g) so++;
	}
	return re;
}
void dij()
{
	for (long long i=0;i<x[0];i++)
	  vis[i]=false,f[i]=9223372036854775807;
	f[1%x[0]]=1;
	add(1,1%x[0]);
	while (g)
	{
		long long x=del();
		if (vis[x]) continue;
		vis[x]=true;
		for (long long i=fr[x];i;i=net[i])
		{
			if (f[to[i]]>f[x]+l[i])
			{
				f[to[i]]=f[x]+l[i];
				add(f[to[i]],to[i]);
			}
		}
	}
}
int main()
{
	cin>>hh;
	cin>>x[0]>>x[1]>>x[2];
	sort(x+0,x+3);
	for (long long i=0;i<x[0];i++)
	{
		addedge(i,(i+x[1])%x[0],x[1]);
		addedge(i,(i+x[2])%x[0],x[2]);
	}
	dij();
	for (long long i=0;i<x[0];i++)
	{
		if (f[i]>hh) continue;
		ans+=(hh-f[i])/x[0]+1;
	}
	cout<<ans<<endl;
	return 0;
}

习题[国家集训队]墨墨的等式 BZOJ链接


参考资料
【1】https://www.luogu.org/problemnew/solution/P3403

原文地址:https://www.cnblogs.com/fmj123/p/Luogu3403.html