您的位置:首页 > 其它

BZOJ2726 [SDOI2012]任务安排

2014-10-08 19:16 316 查看
[]

It must be true that today isn't suitable for coding.

[Solution]

Reverse the producing process, which means set i as n - i + 1 in the original problem.

Let Ti = sigma(t1~ti), Ci = sigma(f1~fi).

Each batch's contributtion to the answer is Ci * (Ti - Tj + s). The DP function can be Fi = Ci * (Ti - Tj + s) + Fj.

Convert the equation to this: Fj = Tj * Ci - Ci * Ti - s * Ci + Fi. Set Ci = k, Fj = y and Tj = x.

Then modify the lower hull by a balanced tree or map.

[Code]

The treap is so ugly that I spent almost the whole after noon and half a evening to debug. Yuck.

#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <memory.h>
#include <map>
#include <algorithm>

using namespace std;

typedef long double exf;
typedef long long qw;
typedef pair <qw, int> dpair;
typedef pair <exf, int> kpair;

#ifdef WIN32
#define lld "%I64d"
#else
#define lld "%lld"
#endif

const int maxn = 300009;
const exf f_inf = 1e100;
const qw inf = 0x3f3f3f3f3f3fLL;

template <class _INT>
void readInt(_INT& s) {
int d;
bool nag = 0;
s = 0;
while (!isdigit(d = getchar()))
if (d == '-')
nag = 1;
while (s = s * 10 + d - 48, isdigit(d = getchar()));
if (nag)
s = -s;
}

int n, s, rt;
qw c[maxn], t[maxn], f[maxn];
exf k[maxn];

namespace treap {
int ls[maxn], rs[maxn], val[maxn], wei[maxn], tn;
qw key[maxn];
inline void lRot(int& p) {
int q = rs[p];
rs[p] = ls[q];
ls[q] = p;
p = q;
}
inline void rRot(int& p) {
int q = ls[p];
ls[p] = rs[q];
rs[q] = p;
p = q;
}
inline void maintain(int& p, bool d) {
if (d) {
if (wei[ls[p]] > wei[p])
rRot(p);
}
else
if (wei[rs[p]] > wei[p])
lRot(p);
}
void init() {
wei[0] = 0;
tn = 0;
}
inline int newNode(qw k0, int v0) {
++ tn;
ls[tn] = 0;
rs[tn] = 0;
val[tn] = v0;
wei[tn] = rand();
key[tn] = k0;
return tn;
}
void ins(int& p, qw k0, int v0) {
if (!p)
p = newNode(k0, v0);
else {
if (k0 < key[p])
ins(ls[p], k0, v0);
else
ins(rs[p], k0, v0);
maintain(p, k0 < key[p]);
}
}
bool ers(int& p, qw k0) {
if (!p)
return 0;
else if (key[p] == k0) {
if (!ls[p])
p = rs[p];
else if (!rs[p])
p = ls[p];
else {
int q = ls[p];
while (rs[q])
q = rs[q];
key[p] = key[q];
val[p] = val[q];
return ers(ls[p], key[p]);
}
return 1;
}
else if (k0 < key[p])
return ers(ls[p], k0);
else
return ers(rs[p], k0);
}
int find(int p, qw k0) {
if (!p)
return -1;
else if (key[p] == k0)
return val[p];
else if (k0 < key[p])
return find(ls[p], k0);
else
return find(rs[p], k0);
}
dpair prv(int p, qw k0) {
if (!p)
return dpair(-inf, -1);
else if (k0 <= key[p])
return prv(ls[p], k0);
else {
dpair a = dpair(key[p], val[p]);
dpair b = prv(rs[p], k0);
if (b. first >= a. first && b. first != -1)
return b;
else
return a;
}
}
dpair suc(int p, qw k0) {
if (!p)
return dpair(inf, -1);
else if (k0 >= key[p])
return suc(rs[p], k0);
else {
dpair a = dpair(key[p], val[p]);
dpair b = suc(ls[p], k0);
if (b. first <= a. first && b. second != -1)
return b;
else
return a;
}
}
kpair searchK(int p, exf k0) {
if (!p)
return kpair(f_inf, -1);
else if (k[val[p]] >= k0) {
kpair a = kpair(k[val[p]], val[p]);
kpair b = searchK(ls[p], k0);
if (b. first <= a. first && b. second != -1)
return b;
else
return a;
}
else
return searchK(rs[p], k0);
}
};

exf getK(int a, int b) {
return ((exf)f[b] - f[a]) / ((exf)t[b] - t[a]);
}

void insK(int x) {
dpair p, q, s;
int tmp;
if ((tmp = treap :: find(rt, t[x])) > -1) {
if (f[tmp] <= f[x])
return;
else
treap :: ers(rt, t[tmp]);
}
if ((p = treap :: prv(rt, t[x])). first > -inf) {
if (k[p. second] < getK(p. second, x))
return;
else {
while ((q = treap :: prv(rt, t[p. second])). first > -inf)
if (k[q. second] > getK(p. second, x)) {
treap :: ers(rt, t[p. second]);
p = q;
}
else
break;
if (p. first > -inf)
k[p. second] = getK(p. second, x);
}
}
if ((s = treap :: suc(rt, t[x])). first < inf) {
while (k[s. second] < getK(x, s. second)) {
treap :: ers(rt, t[s. second]);
s = treap :: suc(rt, t[x]);
if (s. second == -1)
break;
}
if (s. second > -1)
k[x] = getK(x, s. second);
else
k[x] = f_inf;
}
else
k[x] = f_inf;
treap :: ins(rt, t[x], x);
}

int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif

srand(29383);
treap :: init();
rt = 0;
readInt(n);
readInt(s);
for (int i = 0; i < n; ++ i) {
readInt(t[n - i]);
readInt(c[n - i]);
}
t[0] = 0;
c[0] = 0;
f[0] = 0;
for (int i = 1; i <= n; ++ i)
t[i] += t[i - 1], c[i] += c[i - 1];
insK(0);
for (int i = 1; i <= n; ++ i) {
int j = treap :: searchK(rt, c[i]). second;
f[i] = f[j] + c[i] * (t[i] - t[j] + s);
insK(i);
}
printf(lld "\n", f
);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: