题解BZOJ-2118 图论 SPFA + SLE 最短路 数论
2017-03-24 16:02
295 查看
先来分析一下吧,我们在这些a里任取一个ai,表示为k,那么这个B%k肯定是在0–k-1之间的,如果一个B满足条件,这个B%k=d,那么(B+k)%k也肯定为d,那其实就是说,只要我们能找到,%k=d的,且满足条件的最小的B,在一直往上加k,直到加到r为止,能有多少个B,(这些B都是符合条件的),就得到了B%k=d所有的可能,在枚举不同的d,累加起来,不就是0–r内全部可能的B值了嘛。同理,0–l-1内所有可能的B值也可以求出,一减不就是l–r内的可能,不就是答案呐!
然后,之所以可以用SPFA,就是因为要求余d时最小的B,用dis[d]保存,首先队首是0,因为余0时,B为0是肯定可以且最小的(非负),所以dis[0]=0,通过加上不同的a,得到新的余数,如果得到相同的余数的话,可以用B较小的来更新did值,也就是“松弛”。
可以用SPFA + SLE优化
然后,之所以可以用SPFA,就是因为要求余d时最小的B,用dis[d]保存,首先队首是0,因为余0时,B为0是肯定可以且最小的(非负),所以dis[0]=0,通过加上不同的a,得到新的余数,如果得到相同的余数的话,可以用B较小的来更新did值,也就是“松弛”。
可以用SPFA + SLE优化
#include "queue" #include "cstdio" #include "cctype" #include "cstring" #define min(a, b) ((a) < (b) ? (a) : (b)) template <class T> inline bool readIn(T &x) { T flag = 1; char ch; while(!(isdigit(ch = (char) getchar())) && ch != EOF) if( ch == '-' ) flag = -1; if(ch == EOF) return false; for(x = ch - 48; isdigit(ch = (char) getchar()); x = (x << 1) + (x << 3) + ch - 48); x *= flag; return true; } template <class T> inline void write(T x) { if (x > 9) write(x / 10); putchar(x % 10 + 48); } template <class T> inline void writeIn(T x) { if (x < 0) { putchar('-'); x = -x; } write(x); } const int MAXN = (int) 5 * 1e5 + 5; typedef long long LL; int n, smin = 0x3f3f3f3f, a[13]; LL l, r, ansl, ansr, dis[MAXN]; inline void initialize() { readIn(n);readIn(l);readIn(r); for(register int i = 1; i <= n; readIn(a[i]), (a[i] ^ 0) ? smin = min(a[i], smin) : smin, ++i); } class BellmanFord { private: bool vis[MAXN]; std::deque<int> q; inline void initialize() { q.clear(); std::fill(dis, dis + smin, (const LL) 1e12 + 5); memset(vis, false, sizeof(int) * (n + 1)); } public: inline void SPFA(int s) { initialize(); dis[s] = 0, vis[s] = true; q.push_front(s); while( !q.empty() ) { int u = q.front(); q.pop_front(); vis[u] = false; for(register int i = 1; i <= n; ++i) { int v = ( u + a[i] ) % ::smin; if( dis[v] > (LL) dis[u] + a[i] ) { dis[v] = (LL) dis[u] + a[i]; if( !vis[v] ) { if( q.empty() || dis[v] < dis[q.front()] ) q.push_front(v); else q.push_back(v); vis[v] = true; } } } } } } SPFA; int main() { initialize(); SPFA.SPFA(0); for(register int i = 0; i < smin; ++i) if(dis[i] <= r) ansr += (r - dis[i]) / smin + 1; for(register int i = 0; i < smin; ++i) if(dis[i] <= l - 1) ansl += ((l - 1) - dis[i]) / smin + 1; writeIn(ansr - ansl); putchar('\n'); }
相关文章推荐
- BZOJ2118 由数论推导至图论!最短路SPFA
- BZOJ 2118 数论+最短路(SPFA) 解题报告
- bzoj 2118 墨墨的等式 - 图论最短路建模
- HDU6166 Senior Pan 解题报告【图论】【SPFA最短路】【随机】
- 洛谷P1144-最短路计算【日常最短路,日常图论,SPFA】
- 蒟蒻的图论总结(2):用Floyd、Dij.和SPFA解决最短路
- 【图论】【单源最短路】【SPFA】pascal+邻接表
- hdu 3416 Marriage Match IV 【图论-网络流-最短路+最大流(spfa + Dinic)】
- 洛谷P1346-电车【日常图论,最短路,SPFA】
- [图论训练]BZOJ 2118: 墨墨的等式 【最短路】
- [bzoj2118] 图论SPFA
- 洛谷P2296-寻找道路【日常图论,最短路,SPFA】
- 图论最短路spfa--poj3013Big chrismas tree
- 图论最短路之spfa
- POJ 3259 Wormholes (图论---最短路 Bellman-Ford || SPFA)
- 图论浅析--最短路之SPFA
- 图论浅析--最短路之SPFA
- 【2018.3.24】模拟赛之六-ssl2550 重要人物【图论,最短路,SPFA】
- 图论总结 Dijkstra Tarjan 最小生成树 二分图 最短路 强连通分量 双连通分量 Bellman-Ford SPFA 二分图染色 Kruskal Prim 网络流 二分图匹配 Dinic
- [最小割最大流 || 最短路] roadblock Dinic && SPFA + SLE