您的位置:首页 > 其它

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,详情请见程序。。。

/**************************************************************
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. 不要问我为什么这么慢!我!也!不!知!道!)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: