luoguP3403 跳楼机

这题的弱化版本。


考虑 \(\bmod x\) 意义下的同余等价类。

每个 \(i\in [0,x-1]\)\((i+y)\bmod x\)\((i+z)\bmod x\) 连边。

要注意的是起点为 \(1\bmod x\),起始 \(dis\)\(1\)

#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
const int V=1e5+5;
ll h;
int x,y,z,mn;
struct node{
    int v;ll dis;
    bool operator<(const node& t)const{return dis>t.dis;}
};
vector<node> g[V];
ll dis[V];
void dij(int st){
    memset(dis,0x3f,sizeof dis);
    priority_queue<node> q;
    q.push({st,dis[st]=1});
    while(!q.empty()){
        auto t=q.top();q.pop();
        int u=t.v;
        if(dis[u]!=t.dis) continue;
        for(auto i:g[u]){
            int v=i.v,w=i.dis;
            if(dis[v]>dis[u]+w)
                dis[v]=dis[u]+w,q.push({v,dis[v]});
        }
    }
}
ll query(ll x){
    ll sum=0;
    for(int i=0;i<mn;++i)
        if(dis[i]<=x) sum+=(x-dis[i])/mn+1;
    return sum;
}
int main(){
    scanf("%lld %d %d %d",&h,&x,&y,&z);
    if(x>y) swap(x,y);if(x>z) swap(x,z);
    mn=x;
    for(int i=0;i<mn;++i) g[i].push_back({(i+y)%mn,y}),g[i].push_back({(i+z)%mn,z});
    dij(1%mn);
    printf("%lld",query(h));
}
posted @ 2026-08-05 10:38  yanzixuan2024  阅读(7)  评论(0)    收藏  举报