墨墨的等式

題目鏈接:墨墨的等式


顯然我們對%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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章