同余最短路
跳楼机
题目背景
DJL 为了避免成为一只咸鱼,来找 srwudi 学习压代码的技巧。
题目描述
Srwudi 的家是一幢
经过改造,srwudi 的跳楼机可以采用以下四种方式移动:
- 向上移动
层; - 向上移动
层; - 向上移动
层; - 回到第一层。
一个月黑风高的大中午,DJL 来到了 srwudi 的家,现在他在 srwudi 家的第一层,碰巧跳楼机也在第一层。DJL 想知道,他可以乘坐跳楼机前往的楼层数。
输入格式
第一行一个整数
第二行三个正整数,分别表示题目中的
输出格式
一行一个整数,表示 DJL 可以到达的楼层数。
样例 #1
样例输入 #1
15
4 7 9
样例输出 #1
9
样例 #2
样例输入 #2
33333333333
99005 99002 100000
样例输出 #2
33302114671
提示
可以到达的楼层有:
题解:
先考虑如何统计答案,如果我们知道一个数
那么如果我们能找到这些数,再去统计不就好了吗,但是会有重复,而且数字太过庞大,无法完全跑出,那么考虑什么时候回重复计数,即当
设计转移方程: 设
我们可以用最短路来优化类似于点
std:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N = 2e5+9;
ll H,ans;
int x,y,z;
int h[N],ver[N],w[N],ne[N],idx;
void add(int u,int v,int val)
{
idx++,ver[idx]= v,ne[idx] = h[u],w[idx] = val,h[u] = idx;
}
queue<int>q;
bool inq[N];
ll dis[N];
void spfa()
{
for(int i = 0;i < x;i++)dis[i] = LLONG_MAX+1;//2^64
q.push(1),inq[1] = 1,dis[1] = 1;
while(!q.empty())
{
int u = q.front();inq[u] = 0,q.pop();
for(int i = h[u];~i;i = ne[i])
{
int v = ver[i];
if(dis[v] > dis[u] + w[i])
{
dis[v] = dis[u] + w[i];
if(!inq[v])q.push(v),inq[v] = 1;
}
}
}
}
int main()
{
scanf("%lld%d%d%d",&H,&x,&y,&z);
if(x == 1 || y == 1 || z == 1)return printf("%lld",H),0;
if(x > y)swap(x,y);
if(x > z)swap(x,z);
memset(h,-1,sizeof h);
for(int i = 0;i < x;i++)
{
add(i,(i+y)%x,y);
add(i,(i+z)%x,z);
}
spfa();
for(int i = 0;i < x;i++)
if(H >= dis[i])ans += (H-dis[i])/x+1;
printf("%lld",ans);
return 0;
}
//putin:
//9223372036854775807
//10 10 10
//putout:
//922337203685477581
[国家集训队]墨墨的等式
题目描述
墨墨突然对等式很感兴趣,他正在研究
输入格式
第一行三个整数
第二行
输出格式
一行一个整数,表示有多少
样例 #1
样例输入 #1
2 5 10
3 5
样例输出 #1
5
提示
对于
对于
对于
和上题一样类似就是加边要多一点也要注意区间
std
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ll;
const int N = 5e6+9;
ll l,r,ans;
int n,a[13];
int h[N],ver[N],w[N],ne[N],idx;
void add(int u,int v,int val)
{
idx++,ver[idx]= v,ne[idx] = h[u],w[idx] = val,h[u] = idx;
}
queue<int>q;
bool inq[N];
ll dis[N];
void spfa()
{
for(int i = 0;i < a[1];i++)dis[i] = LLONG_MAX+1;//2^64
q.push(0),inq[0] = 1,dis[0] = 0;
while(!q.empty())
{
int u = q.front();inq[u] = 0,q.pop();
for(int i = h[u];~i;i = ne[i])
{
int v = ver[i];
if(dis[v] > dis[u] + w[i])
{
dis[v] = dis[u] + w[i];
if(!inq[v])q.push(v),inq[v] = 1;
}
}
}
}
int main()
{
scanf("%d%lld%lld",&n,&l,&r);
for(int i = 1;i <= n;i++)scanf("%d",&a[i]);
sort(a+1,a+1+n);
memset(h,-1,sizeof h);
for(int i = 0;i < a[1];i++)
{
for(int j = 2;j <= n;j++)
add(i,(i+a[j])%a[1],a[j]);
}
spfa();
for(int i = 0;i < a[1];i++)
{
if(r < dis[i])continue;
if(r == dis[i])
{
ans++;
continue;
}
if(l-1 <= dis[i])
{
ans += (r-dis[i])/a[1]+1;
continue;
}
ans += (r-dis[i])/a[1]+1 - ((l-1-dis[i])/a[1]+1);//应该是l-1
}
printf("%lld",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!