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 }

 

posted @ 2018-10-18 19:50  Unstoppable728  阅读(243)  评论(0编辑  收藏  举报