题目
墨墨突然对等式很感兴趣,他正在研究 (sum_{i=1}^n a_ix_i=b) 存在非负整数解的条件,
他要求你编写一个程序,给定 (n, a_{1dots n}, l, r),求出有多少 (bin[l,r]) 可以使等式存在非负整数解。
分析
选取一个较小的数(m),设(dis[x])表示得到的最小数在模(m)意义下为(x),
那么在([l,r])内答案为(sum (r-dis[x])/m-(l-1-dis[x])/m)
代码
#include <cstdio>
#include <cstring>
#include <queue>
#define rr register
using namespace std;
const int N=5000011;
long long dis[N],v[N],l,r,ans;
int mn=N,n,a[21],T; queue<int>q;
signed main(){
scanf("%d%lld%lld",&T,&l,&r);
for (rr int x;T;--T){
scanf("%d",&x);
if (!x) continue;
a[++n]=x,mn=mn>x?x:mn;
}
memset(dis,0x3f,sizeof(dis)),
dis[0]=0,q.push(0),v[0]=1;
while (!q.empty()){
rr int x=q.front(); q.pop();
for (rr int i=1;i<=n;++i){
rr int z=(x+a[i])%mn;
if (dis[z]>dis[x]+a[i]){
dis[z]=dis[x]+a[i];
if (!v[z]) v[z]=1,q.push(z);
}
}
v[x]=0;
}
for (rr int i=0;i<mn;++i)
if (dis[i]^dis[mn]){
if (dis[i]<=r) ans+=(r-dis[i])/mn+1;
if (dis[i]<l) ans-=(l-dis[i]-1)/mn+1;
}
return !printf("%lld",ans);
}