1. 程式人生 > >BZOJ 2118 墨墨的不等式 數論 + 最短路 + 計數

BZOJ 2118 墨墨的不等式 數論 + 最短路 + 計數

ace ret space log const 最短 fin push bzoj

 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 }

BZOJ 2118 墨墨的不等式 數論 + 最短路 + 計數