1. 程式人生 > >BZOJ2118: 墨墨的等式(最短路構造/同餘最短路)

BZOJ2118: 墨墨的等式(最短路構造/同餘最短路)

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

解題思路:

詳見

->洛谷跳樓機

其實就是成了n元

用其他n-1元在第n元模環境下最短路。

程式碼:

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 typedef long long lnt;
 6 struct pnt{
 7     int hd;
 8     int no;
 9     lnt dis;
10     bool vis;
11     bool friend operator < (pnt x,pnt y)
12 { 13 return x.dis>y.dis; 14 } 15 }p[1000000]; 16 struct ent{ 17 int twd; 18 int lst; 19 lnt vls; 20 }e[10000000]; 21 lnt a[1000000]; 22 int n,m; 23 int cnt; 24 lnt Bmin,Bmax; 25 lnt ans; 26 std::priority_queue<pnt>Q; 27 void ade(int f,int t,lnt v) 28 { 29 cnt++;
30 e[cnt].twd=t; 31 e[cnt].lst=p[f].hd; 32 e[cnt].vls=v; 33 p[f].hd=cnt; 34 return ; 35 } 36 void Dij(void) 37 { 38 for(int i=0;i<a[1];i++) 39 { 40 p[i].dis=0x3f3f3f3f3f3f3f3fll; 41 p[i].no=i; 42 } 43 p[0].dis=0; 44 Q.push(p[0]); 45 while(!Q.empty()) 46 { 47 int x=Q.top().no; 48 Q.pop(); 49 if(p[x].vis) 50 continue; 51 p[x].vis=true; 52 for(int i=p[x].hd;i;i=e[i].lst) 53 { 54 int to=e[i].twd; 55 if(p[to].dis>p[x].dis+e[i].vls) 56 { 57 p[to].dis=p[x].dis+e[i].vls; 58 Q.push(p[to]); 59 } 60 } 61 } 62 return ; 63 } 64 int main() 65 { 66 scanf("%d%lld%lld",&n,&Bmin,&Bmax); 67 if(n==0) 68 { 69 printf("0\n"); 70 return 0; 71 } 72 for(int i=1;i<=n;i++) 73 { 74 scanf("%lld",&a[i]); 75 if(a[i]==0) 76 { 77 n--; 78 i--; 79 } 80 } 81 for(int i=2;i<=n;i++) 82 for(int j=0;j<a[1];j++) 83 ade(j,(j+a[i])%a[1],a[i]); 84 Dij(); 85 for(int i=0;i<a[1];i++) 86 { 87 if(p[i].dis>Bmax) 88 continue; 89 ans+=(Bmax-p[i].dis)/a[1]+1; 90 if(p[i].dis<Bmin) 91 ans-=(Bmin-p[i].dis-1)/a[1]+1; 92 } 93 printf("%lld\n",ans); 94 return 0; 95 }