bzoj 3672 [Noi2014]购票 (线段树+凸壳)

来源:互联网 发布:数据分析ppt怎么做 编辑:程序博客网 时间:2024/06/04 17:52
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <bitset>#include <vector>using namespace std;#define N 200020#define M 400020#define mod 1000000007#define inf 0x3f3f3f3f#define LL long long#define ls (i << 1)#define rs (ls | 1)#define md (ll + rr >> 1)#define lson ll, md, ls#define rson md + 1, rr, rsint n, t;int fst[N], nxt[M], vv[M], e;LL cost[M];int p[N], fa[N];LL s[N], q[N], l[N];int dep[N], tp[N];int stk[N], top;LL dis[N];LL dp[N];void init() {memset(fst, -1, sizeof fst);e = 0;}void add(int u, int v, LL c) {cost[e] = c, vv[e] = v, nxt[e] = fst[u], fst[u] = e++;}int calc(LL d, LL x) {if(d == 0) return 1;int l = 0, r = top - 1;while(l < r) {int mid = (l + r) / 2;if(d - dis[stk[mid]] <= x)r = mid;else l = mid + 1;}return stk[l];}void dfs1(int u, int d) {tp[u] = calc(dis[u], l[u]);stk[top++] = u;dep[u] = d;for(int i = fst[u]; ~i; i = nxt[i]) {int v = vv[i];dis[v] = dis[u] + cost[i];dfs1(v, d + 1);}top--;}struct node {LL x, y;node() {}node(LL x, LL y):x(x), y(y) {}}pool[N * 20];int pool_sz;node* creat(int len) {node *ret = pool + pool_sz;pool_sz += len;return ret;}struct change {int pos;node a;int len;int i;change() {}change(int pos, node a, int len, int i):pos(pos), a(a), len(len), i(i) {}}cc[N * 20];int cc_cnt;struct ch {node *p;int len;void insert(node v, int x) {if(len == 0 || len == 1) {cc[cc_cnt++] = change(len, p[len], len, x);p[len++] = v;return;}int l = 0, r = len - 1;while(l < r) {int mid = (l + r) / 2;node a = p[mid + 1];node b = p[mid];if(1.0 * (v.y - a.y) / (v.x - a.x) < 1.0 * (a.y - b.y) / (a.x - b.x)) r = mid;else l = mid + 1;}cc[cc_cnt++] = change(l + 1, p[l + 1], len, x);p[l + 1] = v;len = l + 2;}LL query(int k) {int l = 0, r = len - 1;while(l < r) {int mid = (l + r) / 2;node a = p[mid + 1], b = p[mid];if(1.0 * (a.y - b.y) / (a.x - b.x) >= k) r = mid;else l = mid + 1;}return p[l].y - k * p[l].x;}void rollback(change &x) {len = x.len;p[x.pos] = x.a;}}ss[N << 2];void build(int ll, int rr, int i) {ss[i].p = creat(rr - ll + 1);ss[i].len = 0;if(ll == rr) return;build(lson);build(rson);}void update(int x, node v, int ll, int rr, int i) {ss[i].insert(v, i);if(ll == rr) {return;}if(x <= md) update(x, v, lson);else update(x, v, rson);}LL query(int l, int r, int v, int ll, int rr, int i) {if(ll == l && rr == r) {return ss[i].query(v);}if(r <= md) return query(l, r, v, lson);if(l > md) return query(l, r, v, rson);return min(query(l, md, v, lson), query(md + 1, r, v, rson));}void dfs2(int u) {if(u == 1) dp[u] = 0;else {dp[u] = query(dep[tp[u]], dep[u] - 1, p[u], 0, n, 1);dp[u] += dis[u] * p[u] + q[u];}int tmp = cc_cnt;update(dep[u], node(dis[u], dp[u]), 0, n, 1);for(int i = fst[u]; ~i; i = nxt[i]) {int v = vv[i];dfs2(v);}while(cc_cnt != tmp) {--cc_cnt;ss[cc[cc_cnt].i].rollback(cc[cc_cnt]);}}int main() {scanf("%d%d", &n, &t);init();for(int i = 2; i <= n; ++i) {scanf("%d%lld%d%lld%lld", &fa[i], &s[i], &p[i], &q[i], &l[i]);add(fa[i], i, s[i]);}dfs1(1, 0);build(0, n, 1);dfs2(1);for(int i = 2; i <= n; ++i) printf("%lld\n", dp[i]);return 0;}

0 0
原创粉丝点击