BZOJ 2118 墨墨的等式(最短路)

 

【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=2118

 

【题目大意】

  求a1x1+a2y2+…+anxn=B在B的取值范围,有多少B可以使等式存在非负整数解。

 

【题解】

  同余最短路,不等式解集计数即可。

 

【代码】

#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
const int N=500010;
namespace DIJKSTRA{
    typedef long long LL;
    const LL INF=0x3f3f3f3f3f3f3f3f;
    typedef pair<LL,int>P;
    priority_queue<P,vector<P>,greater<P> >Q;
    int a[N],n,m; LL d[N];
    void Initialize(){
        int x,i;
        sort(a,a+n); m=a[0]; d[0]=0;
        for(i=1;i<m;i++)d[i]=INF;Q.push(P(0,0));
        while(!Q.empty()){
            P t=Q.top();Q.pop();
            if(d[t.second]<t.first)continue;
            for(x=t.second,i=1;i<n;i++){
                if(d[x]+a[i]<d[(x+a[i])%m])Q.push(P(d[(x+a[i])%m]=d[x]+a[i],(x+a[i])%m));
            }
        }
    }
    LL Query(LL x){
        LL res=0;
        for(int i=0;i<m;i++)if(d[i]<=x)res+=(x-d[i])/m+1;
        return res;
    }
}
long long L,R;
int main(){
    using namespace DIJKSTRA;
    scanf("%d%lld%lld",&n,&L,&R);
    for(int i=0;i<n;i++)scanf("%d",&a[i]);
    Initialize();
    printf("%lld\n",Query(R)-Query(L-1));
    return 0; 
}
posted @ 2017-09-05 14:53  forever97  阅读(250)  评论(0编辑  收藏  举报