(最短路) bzoj 2118
2118: 墨墨的等式
Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 479 Solved: 183
[Submit][Status][Discuss]
Description
墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N、{an}、以及B的取值范围,求出有多少B可以使等式存在非负整数解。
Input
输入的第一行包含3个正整数,分别表示N、BMin、BMax分别表示数列的长度、B的下界、B的上界。输入的第二行包含N个整数,即数列{an}的值。
Output
输出一个整数,表示有多少b可以使等式存在非负整数解。
Sample Input
2 5 10
3 5
3 5
Sample Output
5
HINT
对于100%的数据,N≤12,0≤ai≤4*10^5,1≤BMin≤BMax≤10^12。
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<cstdlib> #include<algorithm> #include<vector> #include<queue> #include<stack> #define INF 1000000000000ll using namespace std; vector<int> e[500005],w[500005]; long long n,a[15],vis[500005]; long long minn; long long l,r,dist[500005]; long long work(long long x,long long y,long long z) { return x<y?0:(((x-y)/z)+1); } int main() { minn=INF; queue<int> q; scanf("%d",&n); scanf("%lld%lld",&l,&r); for(int i=1;i<=n;i++) scanf("%d",&a[i]),minn=min(minn,a[i]); for(int i=1;i<=n;i++) { for(int j=0;j<minn;j++) { e[j].push_back((j+a[i])%minn); w[j].push_back(a[i]); } } for(int i=0;i<minn;i++) dist[i]=INF; dist[0]=0; q.push(0); vis[0]=1; while(!q.empty()) { int x=q.front(); q.pop(); vis[x]=0; for(int i=0;i<e[x].size();i++) { int v=e[x][i]; if(dist[v]>dist[x]+w[x][i]) { dist[v]=dist[x]+w[x][i]; if(!vis[v]) { vis[v]=1; q.push(v); } } } } long long ans=0; for(int i=0;i<minn;i++) ans+=work(r,dist[i],minn)-work(l-1,dist[i],minn); printf("%lld\n",ans); return 0; }