BZOJ 2118 墨墨的不等式 数论 + 最短路 + 计数

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 const LL INF = 50000000000000000ll; 
 4 #define maxn 500010
 5 using namespace std;
 6 LL l, r;
 7 LL ans = 0;
 8 int n, a[maxn];
 9 LL mi = INF, d[maxn];
10 LL solve(LL x){
11     if(x > r) return 0;
12     else if(x >= l){
13         return ((r - x)/mi + 1ll);
14     }
15     else{
16         return ((r - x)/mi - (l - 1 - x)/mi);
17     }
18 }
19 void spfa(){
20     bool vis[maxn];
21     memset(vis, false, sizeof(vis));
22     for(int i = 0; i < mi; i ++){
23         d[i] = INF;
24     }
25     d[0] = 0;
26     vis[0] = true;
27     queue<int> Q;
28     Q.push(0);
29     int p, now;
30     while(!Q.empty()){
31         p = Q.front();
32         Q.pop();
33         vis[p] = false;
34         for(int i = 1; i <= n; i ++){
35             if(a[i] == mi) continue;
36             now = (p + a[i]) % mi;
37             if(d[now] > d[p] + a[i]){
38                 d[now] = d[p] + a[i];
39                 if(!vis[now]){
40                     vis[now] = true;
41                     Q.push(now);
42                 }
43             }
44         }
45     }
46 }
47 int main(){
48     cin >> n >> l >> r; 
49     for(int i = 1; i <= n; i ++){
50         scanf("%d",&a[i]);
51         if(a[i] == 0){
52             i --, n --;
53         }
54         else
55         mi = min(mi, (LL)a[i]);
56     }
57     if(mi == 1){
58         cout << (r - l + 1) << endl;
59         return 0;
60     }
61     spfa();
62     for(int i = 0; i < mi; i ++){
63         if(d[i] == INF) continue;
64         ans += solve((LL)d[i]);
65     }    cout << ans;
66     return 0;
67 }

 

posted on 2017-10-18 01:08  poler  阅读(282)  评论(0编辑  收藏  举报

导航