bzoj2118 墨墨的等式

2118: 墨墨的等式

Time Limit: 10 Sec  Memory Limit: 259 MB

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≤5*10^5,1≤BMin≤BMax≤10^12。

Tips:

  此题不作多讲,看代码即可;

Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define MOD 500008
using namespace std;
long long a[18],tot,n;
long long qu[500008],d[500008],st,ed;
long long l,r;
bool boo[500008];

long long query(long long maxx){
    long long res=0;
    for(int i=0;i<a[1];i++){
        if(d[i]<=maxx){
            res+=(maxx-d[i])/a[1]+1;
        }
    }
    return res;
}

int main(){
    tot=0;
    scanf("%lld%lld%lld",&n,&l,&r);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        if(!a[i]) { i--; n--; continue; }  
    }
    sort(a+1,a+n+1);
    for(int i=1;i<a[1];i++)
        d[i]=r+1;
    d[0]=0;
    memset(boo,0,sizeof(boo));
    qu[1]=0; boo[0]=true;
    st=0; ed=1;
    while(st!=ed){
        st=st%MOD+1;
        int x=qu[st];
        for(int i=1;i<=n;i++){
            int y=(x+a[i])%a[1];
            if(d[y]>d[x]+a[i]){
                d[y]=d[x]+a[i];
                if(!boo[y]){
                    boo[y]=false;
                    ed=ed%MOD+1;
                    qu[ed]=y;
                }
            }
        }
        boo[x]=0;
    }
    printf("%lld
",query(r)-query(l-1));
}
原文地址:https://www.cnblogs.com/WQHui/p/7502174.html