BZOJ2726 [SDOI2012]任务安排

来源:互联网 发布:淘宝美图软件 编辑:程序博客网 时间:2024/05/01 13:09

[]

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"#endifconst 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);elseins(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);elsereturn 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);elsereturn 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;elsereturn 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;elsereturn 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;elsereturn a;}elsereturn 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;elsetreap :: 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;}elsebreak;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);elsek[x] = f_inf;}elsek[x] = f_inf;treap :: ins(rt, t[x], x);}int main() {#ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin);#endifsrand(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[n]);}


0 0