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.
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 ); }
相关文章推荐
- BZOJ_2726_[SDOI2012]任务安排_斜率优化+二分
- [bzoj2726][SDOI2012]任务安排 ——斜率优化,动态规划,二分,代价提前计算
- bzoj 2726: [SDOI2012]任务安排
- [SDOI2012]任务安排 BZOJ2726 斜率优化+二分查找
- bzoj2726 [SDOI2012]任务安排(斜率优化+cdq分治)
- BZOJ2726: [SDOI2012]任务安排
- bzoj 2726 [SDOI2012]任务安排 CDQ分治维护凸包 dp
- [BZOJ2726][SDOI2012]任务安排(DP+凸壳二分)
- 【bzoj2726】[SDOI2012]任务安排
- bzoj 2726: [SDOI2012]任务安排
- 【SDOI2012】bzoj2726 任务安排
- bzoj 2726: [SDOI2012]任务安排【cdq+斜率优化】
- 【BZOJ2726】[SDOI2012]任务安排 斜率优化+cdq分治
- [BZOJ2726][SDOI2012]任务安排(斜率优化dp+cdq分治)
- BZOJ 2726 [SDOI2012]任务安排
- BZOJ 2726: [SDOI2012]任务安排( dp + cdq分治 )
- BZOJ2726 [SDOI2012]任务安排 【斜率优化 + cdq分治】
- BZOJ:2726: [SDOI2012]任务安排(斜率优化)
- bzoj 2726 [SDOI2012]任务安排(斜率DP+CDQ分治)
- bzoj 2726: [SDOI2012]任务安排