前置芝士:同余最短路
这题其实就是例题的强化版,还是以最小的a[i]为除数做与例题相同的建模方法即可。
#include <bits/stdc++.h> using namespace std; const long long MAXA = 5e5 + 10; struct node{ long long pre, to, val; }edge[MAXA * 20]; long long head[MAXA], tot; long long n, bmi, bmx; long long a[20]; long long dis[MAXA], vis[MAXA]; queue<long long> q; void add(long long u, long long v, long long l) { edge[++tot] = node{head[u], v, l}; head[u] = tot; } void spfa() { memset(dis, 0x3f, sizeof(dis)); dis[0] = 0; vis[0] = 1; q.push(0); while (!q.empty()) { long long x = q.front(); q.pop(); for (long long i = head[x]; i; i = edge[i].pre) { long long y = edge[i].to; if (dis[y] > dis[x] + edge[i].val) { dis[y] = dis[x] + edge[i].val; if (!vis[y]) { vis[y] = 1; q.push(y); } } } vis[x] = 0; } } long long solve(long long x) { long long ret = 0; for (long long i = 0; i < a[1]; i++) { if (dis[i] <= x) { ret += (x - dis[i]) / a[1] + 1; } } return ret; } int main() { cin >> n >> bmi >> bmx; for (long long i = 1; i <= n; i++) { cin >> a[i]; } for (long long i = 0; i < a[1]; i++) { for (long long j = 2; j <= n; j++) { add(i, (i + a[j]) % a[1], a[j]); } } spfa(); cout << solve(bmx) - solve(bmi - 1); return 0; }