BZOJ2118 墨墨的等式
2015-03-22 23:12
239 查看
为什么A掉的人这么多没有写题解QAQ
首先我们选出最小的a,不妨设为a[1],对于某个数x,先用最小的a来拼,使得x = a[1] * p + r (0 ≤ r < a[1])
然后是很神奇的地方:建图最短路!
对于每个模数r我们建一个点p
然后我们暴力枚举点u,再暴力枚举选择方式a[i],令v = (u + a[i]) % a[1],则u向v连边权值为(u + a[i]) / a[1],意思是从方案中退掉这么多的a[1]再加上a[i]才能从u到v
于是我们从0开始跑单源最短路,0到每个点的最短路d表示至少要退掉这么多a[1]才能到达,也即当x = (d + k) * a[i] + r (0 ≤ k)时才可以做到
然后就没了QAQ,详情请见程序。。。
View Code
(p.s. 不要问我为什么这么慢!我!也!不!知!道!)
首先我们选出最小的a,不妨设为a[1],对于某个数x,先用最小的a来拼,使得x = a[1] * p + r (0 ≤ r < a[1])
然后是很神奇的地方:建图最短路!
对于每个模数r我们建一个点p
然后我们暴力枚举点u,再暴力枚举选择方式a[i],令v = (u + a[i]) % a[1],则u向v连边权值为(u + a[i]) / a[1],意思是从方案中退掉这么多的a[1]再加上a[i]才能从u到v
于是我们从0开始跑单源最短路,0到每个点的最短路d表示至少要退掉这么多a[1]才能到达,也即当x = (d + k) * a[i] + r (0 ≤ k)时才可以做到
然后就没了QAQ,详情请见程序。。。
/************************************************************** Problem: 2118 User: rausen Language: C++ Result: Accepted Time:5228 ms Memory:74848 kb ****************************************************************/ #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; typedef long long ll; const int N = 4e5 + 5; const int M = 5e6 + 5; struct edge { int next, to, v; edge() {} edge(int _n, int _t, int _v) : next(_n), to(_t), v(_v) {} } e[M]; int first , tot; struct heap_node { int v, to; heap_node() {} heap_node(int _v, int _to) : v(_v), to(_to) {} inline bool operator < (const heap_node &a) const { return v > a.v; } }; int n; ll mn, mx, ans; int a[15], dis ; priority_queue <heap_node> h; inline void add_edge(int x, int y, int z) { e[++tot] = edge(first[x], y, z), first[x] = tot; } inline void add_to_heap(const int p) { static int x; for (x = first[p]; x; x = e[x].next) if (dis[e[x].to] == -1) h.push(heap_node(e[x].v + dis[p], e[x].to)); } void Dijkstra() { memset(dis, -1, sizeof(dis)); while (!h.empty()) h.pop(); dis[0] = 0, add_to_heap(0); int p; while (!h.empty()) { if (dis[h.top().to] != -1) { h.pop(); continue; } p = h.top().to; dis[p] = h.top().v; h.pop(); add_to_heap(p); } } int main() { int i, j; scanf("%d%lld%lld", &n, &mn, &mx); mn -= 1; for (i = 1; i <= n; ++i) { scanf("%d", a + i); if (a[i] < a[1]) swap(a[i], a[1]); } for (i = 0; i < a[1]; ++i) for (j = 2; j <= n; ++j) add_edge(i, (i + a[j]) % a[1], (i + a[j]) / a[1]); Dijkstra(); for (i = 0; i < a[1]; ++i) { if (dis[i] == -1) continue; ans += max(0ll, (mx - i) / a[1] - max(0ll, max((mn - i) / a[1], (ll) dis[i] - 1))); } printf("%lld\n", ans); return 0; }
View Code
(p.s. 不要问我为什么这么慢!我!也!不!知!道!)
相关文章推荐
- BZOJ 2118 墨墨的等式 堆优化Dijkstra
- 【bzoj2118】 墨墨的等式
- 【bzoj2118】墨墨的等式
- bzoj2118 墨墨的等式 最短路
- 【BZOJ2118】墨墨的等式
- 【BZOJ 2118】 墨墨的等式(Dijkstra)
- BZOJ 2118 墨墨的等式
- 【BZOJ】2118 墨墨的等式
- 【bzoj2118】墨墨的等式 最短路建模
- BZOJ 2118: 墨墨的等式
- BZOJ_2118_墨墨的等式_最短路
- 【BZOJ 2118】墨墨的等式
- BZOJ 2118 墨墨的等式(最短路)
- BZOJ2118: 墨墨的等式
- [bzoj2118]墨墨的等式【dijk+堆】
- Bzoj2118 墨墨的等式
- BZOJ 2118 墨墨的等式
- 数论+spfa算法 bzoj 2118 墨墨的等式
- [bzoj2118] 墨墨的等式 模数分类 最短路
- bzoj 2118 墨墨的等式 - 图论最短路建模