题目链接:墨墨的等式
显然我们对%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;
}