同余最短路学习笔记
今天讲课讲到了同余最短路。简单记一下,防止之后忘了这个坑。
简介
同余最短路,可以用来处理问题:
1.「给定 n 个数,求这些数能拼出多少其他数(选数数量不限)」
2.「给 n 个数,求这些数不能拼出的最大 or 最小值」
3.「至少拼几次才能拼出模 k 余 x 的数」。
同余最短路可以通过同余来构造状态,类比差分约束的转换思路,利用同余构造的状态可以看做单源最短路中的点。同余最短路的转移通常是:
例题1:P3403 跳楼机
首先考虑,如果我只用
所以考虑对于与余数为
因此考虑,点编号就是余数,不断的往上添加
对其跑最短路,
因为最大限制为
嗯我
特别注意当
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
const int N=2e5+10;
ll h,ans;
int t,y,z;
priority_queue<pair<ll,int> >q;
int idx,e[N],w[N],nxt[N],head[N];
int vis[N];
ll d[N];
void add(int x,int y,int z){
e[++idx]=y;
w[idx]=z;
nxt[idx]=head[x];
head[x]=idx;
}
void dij(){
memset(d,0x3f,sizeof d);
d[1%t]=1;
q.push(make_pair(-1,1%t));
while(q.size()){
int x=q.top().second;
q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x];i;i=nxt[i]){
if(d[e[i]]>d[x]+w[i]){
d[e[i]]=d[x]+w[i];
q.push(make_pair(-d[e[i]],e[i]));
}
}
}
}
int main(){
scanf("%lld%d%d%d",&h,&t,&y,&z);
for(int i=0;i<t;i++){
add(i,(i+y)%t,y);
add(i,(i+z)%t,z);
}
dij();
for(int i=0;i<t;i++) if(h>=d[i]&&d[i]!=INF) ans+=((h-d[i])/t+1);
printf("%lld",ans);
}
例题 2:P2371 [国家集训队] 墨墨的等式
做法类比上一题,对于以一个数作为基准建边跑同余最短路,最后对于区间类似前缀和统计。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5e6+10;
ll l,r,ans;
ll d[N];
int n;
int vis[N];
int idx,e[N],w[N],nxt[N],head[N];
priority_queue<pair<int,int> > q;
void add(int x,int y,int z){
e[++idx]=y;
w[idx]=z;
nxt[idx]=head[x];
head[x]=idx;
}
void dij(){
memset(d,0x3f,sizeof d);
d[0]=0;
q.push(make_pair(0,0));
while(q.size()){
int x=q.top().second;
q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=head[x];i;i=nxt[i]){
if(d[e[i]]>d[x]+w[i]){
d[e[i]]=d[x]+w[i];
q.push(make_pair(-d[e[i]],e[i]));
}
}
}
}
int main(){
int x,y;
scanf("%d%lld%lld%d",&n,&l,&r,&x);
for(int i=1;i<n;i++){
scanf("%d",&y);
for(int i=0;i<x;i++) add(i,(i+y)%x,y);
}
dij();
l--;
for(int i=0;i<x;i++){
if(r>=d[i]) ans+=(r-d[i])/x+1;
if(l>=d[i]) ans-=(l-d[i])/x+1;
}
printf("%lld",ans);
return 0;
}
注意这个题,数组需要开 5e6。开大了会 MLE,小了会显示 TLE。别问我怎么知道的。
本文作者:Moyyer_suiy
本文链接:https://www.cnblogs.com/Moyyer-suiy/p/17814080.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步