題目鏈接:墨墨的等式
顯然我們對%a[1]得到每個能到的最小值,然後再用a[1]遞加上去即可。
得到能到的最小值跑同餘最短路即可。
但是要注意計算的時候比如計算x,那麼要d[i]<=x才能計算。
AC代碼:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+10;
int n,a[N],L,R,d[N],vis[N],res;
void Dijkstra(){
priority_queue<pair<int,int> > q; q.push({0,0}); memset(d,0x3f,sizeof d); d[0]=0;
while(q.size()){
int u=q.top().second; q.pop();
if(vis[u]) continue; vis[u]=1;
for(int i=2;i<=n;i++) if(d[(u+a[i])%a[1]]>d[u]+a[i]){
d[(u+a[i])%a[1]]=d[u]+a[i]; q.push({-d[(u+a[i])%a[1]],(u+a[i])%a[1]});
}
}
}
inline int calc(int x,int id){return (x-d[id])/a[1]+1;}
signed main(){
cin>>n>>L>>R;
for(int i=1;i<=n;i++) cin>>a[i];
Dijkstra();
for(int i=0;i<a[1];i++){
if(d[i]<=R) res+=calc(R,i);
if(d[i]<=L-1) res-=calc(L-1,i);
}
cout<<res;
return 0;
}