概念:
属于最短路的拓展应用,常用于类似下面的模型:
已知一个带权图,现在需要求出从点
u 到点
v 是否存在一条路径,满足路径长度为
L,每条边可以重复经过。其中数据满足:
L≤1018 ∀w≤104
当然,题目也可以换成求出一个区间
[minL,maxL] 内的方案数,最小的合法长度,看题目的具体要求。
以简单的例题开始
Srwudi的家是一幢
h层的摩天大楼。由于前来学习的蒟蒻越来越多,srwudi改造了一个跳楼机,使得访客可以更方便的上楼。
经过改造,srwudi的跳楼机可以采用以下四种方式移动:
- 向上移动
x层;
- 向上移动
y层;
- 向上移动
z层;
- 回到第一层。
一个月黑风高的大中午,DJL来到了srwudi的家,现在他在srwudi家的第一层,碰巧跳楼机也在第一层。DJL想知道,他可以乘坐跳楼机前往的楼层数。
h≤263−1,x,y,z≤105
题解(瞎吹)
如果不考虑
h的大小问题,那么我们可以得到一个简单的dp:
f(i)=f(i−x) V f(i−y) V f(i−z)f(1)=true(或运算符用V表示)
因为
h过大,这个dp的时空复杂度过高,不能接受,因此需要进行优化。
最终上升到的楼层和操作的顺序没有关系,所以我们可以将一种操作堆积起来,将一个到达的楼层分解为:
h=ax+by+cz
首先我们用最短路的方式求出数组
f(),不知道怎么计算的到时候看代码
f(i)=hmin{hmodz=i}其中h=ax+by
翻译成人话就是用前两种操作到达一个高度h,这个高度和z取模的结果是i,
f(i)表示的是最小的h。
求出这个
f()之后,我们从楼层
f(i)出发,只用操作3能够到达的楼层有:
⌊xh−f(i)⌋+1 (1)
那么这个答案是否有遗漏呢,假设我们从
f(i)出发,用操作1,2再走到了一个楼层
h′,这个楼层依然满足
h′modz=i,那么可以得到:
h′=⌊zh′⌋z+i∵h=⌊zh⌋z+i∴h′−h=(⌊zh′⌋−⌊zh⌋)z
所以这个楼层
h′其实也可以由
h使用几次操作3得到,也就说它会被计算到式子(1)中,不会被遗漏,那么我们最终的答案可以表示为:
ans=i=0∑n⌊xh−f(i)⌋+1
这样的计算是不会用重复的。简单的证明(乱搞)如下:
使用反证法,如果同一个楼层能使用两种不同的方式得到,如果
x,y,z互不相等,那么:
a1x+b1y+c1z=a2x+b2y+c2z=h
两个多项式相等,则这两多项式最高次数相同,且对应次数项的系数相同.
那么得到
a1=a2,b1=b2,c1=c2
显然两个方法其实是同一个。
如果
x,y,z有两个是相等的,那么就可以将这两个相等字母所在的单项式合并,依然是类似于上面的结果。
一道难一点的题
墨墨突然对等式很感兴趣,他正在研究等式
a1x1+a2x2+…+anxn=B
存在非负整数解的条件,他要求你编写一个程序,给定
N、
{an}、以及
B的取值范围,求出有多少B可以使等式存在非负整数解。
N≤10,∀ai≤5×105,1≤Bmin≤Bmax≤1012
题解(瞎吹)
显然用
[0,Bmax)的方案数减去
[0,Bmin−1)的方案数就是题目要求的答案了。
找到序列
a中最小的元素
m,然后将序列中的每个元素分别对其取模,得到一个新的序列
t。这样的话,如果一个
B是合法的,那么
B+mx(x∈N)也是合法的。而我们只需要知道一个对
m取模为
i的最小
B是多少,那么就知道在区间
[0,Bmax]中有多少个数对
m取模为
i。
首先我们做一个最短路,对于点
u(u<m)和点
(u+ai)modm建一条边权为
ai的边,然后求出数组
f(u),其意义和上一道题目差不多。
而求出
[0,Bmax)中的方案数可以使用这一条式子,而
[0,Bmin−1)的方案树也是类似的:
i=0∑m−1⌊mBmax−f(i)⌋+1
关于不重复和不遗漏的问题就交给正在看的各位dalao了。
再难一点的题目
题面
有一个有
n个点的无向图,共有
m条边,每一条边
ei的边权为
wi,现在要找到一条从点
1到点
n的路径,其长度恰好为
L。问是否存在这样的路径。
n≤50,wi≤3×104,len≤1018
题解(可能会TLE)
首先定义同余最短路的距离数组
dis[u][m]表示从开始到点
u,经过的路径长度
l是满足
l≡m (mod M)的最小
l,显然可以通过spfa求出。
对于与点
n直接相连的一个点
v,它们之间的边
e的长度为
w,显然到达该点之后在
e上来回走奇数数次后可以到达点
n,如果经过一条合法的路径(题目要求的路径)是经过这一条边的,那么
l可以分解为
l1+2aw,而这个
l1要满足:
l1≡l (mod 2w),所以这个
l1可以被认为是
dis[v][lmod2w]+2w,那么如果式子可以表示
l那么就需要满足
dis[v][lmod2w]≤l,于是同余最短路中的
M=2w。
那么最终的算法表示为:
枚举一个端点为
n的边,按照如上的方式计算出
dis数组,接着判断。