(最短路) bzoj 2118

2118: 墨墨的等式

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 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

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;
}

  

posted @ 2015-05-21 19:41  waterfull  阅读(440)  评论(0编辑  收藏  举报