题目链接

【luoguP2371】 [国家集训队]墨墨的等式

考虑将所有的\(a_1x_1+a_2x_2+……+a_nx_n=B\)\(a_1\)取模,那么所有可达到的B就分为了\(0\)~\(a_1-1\)

如果对\(a_1\)取模为\(k\)的一类\(B\)中最小的\(B\)\(dis[k]\),那么\(dis[k]+a_1,dis[k]+a_1*2,……\)都是可以取到的,

所以对于每一类求最短路,最后统计答案就行了

#include<iostream>
#include<cstring>
#include<cstdio>
#define int long long
using namespace std;

const int N=15;
const int M=500010;
const int INF=0x3f3f3f3f;

int n,a[N],Bmin,Bmax,am=INF;
int dis[M],que[5000010],head,tail;
bool inque[M];

signed main()
{
	scanf("%lld%lld%lld",&n,&Bmin,&Bmax);
	for(int i=1;i<=n;++i)
		scanf("%lld",&a[i]),am=min(am,a[i]);
	memset(dis,0x3f,sizeof(dis));
	dis[0]=0;
	que[++tail]=0;
	while(head<tail){
		int u=que[++head];
		inque[u]=0;
		for(int i=1;i<=n;++i){
			int v=(u+a[i])%am;
			if(dis[v]>dis[u]+a[i]){
				dis[v]=dis[u]+a[i];
				if(!inque[v]){
					que[++tail]=v;
					inque[v]=1;
				}
			}
		}
	}
	int ans=0;
	for(int i=0;i<am;++i)
	  if(dis[i]<=Bmax){
		ans+=(Bmax-dis[i])/am+1;
		if(dis[i]<Bmin)
			ans-=(Bmin-1-dis[i])/am+1;
	}
	printf("%lld\n",ans);
	return 0;
}

相关文章:

  • 2021-07-30
  • 2021-06-10
  • 2021-07-03
  • 2021-08-01
  • 2022-03-02
  • 2021-12-02
  • 2022-12-23
  • 2021-09-14
猜你喜欢
  • 2021-09-02
  • 2022-12-23
  • 2021-09-23
  • 2022-12-23
  • 2021-12-12
  • 2022-12-23
  • 2021-07-27
相关资源
相似解决方案