左偏树初步 bzoj2809 & bzoj4003
2016-02-06 00:39
387 查看
看着百度文库学习了一个。
总的来说,左偏树这个可并堆满足 堆的性质 和 左偏 性质。
bzoj2809: [Apio2012]dispatching
把每个忍者先放到节点上,然后从下往上合并,假设到了这个点 总值 大于 预算,那么我们把这个 大根堆 的堆顶弹掉就好了,剩下的就是可合并堆。
感谢prey :)
View Code
总的来说,左偏树这个可并堆满足 堆的性质 和 左偏 性质。
bzoj2809: [Apio2012]dispatching
把每个忍者先放到节点上,然后从下往上合并,假设到了这个点 总值 大于 预算,那么我们把这个 大根堆 的堆顶弹掉就好了,剩下的就是可合并堆。
感谢prey :)
#include <bits/stdc++.h> #define rep(i, a, b) for (int i = a; i <= b; i++) #define drep(i, a, b) for (int i = a; i >= b; i--) #define REP(i, a, b) for (int i = a; i < b; i++) #define mp make_pair #define pb push_back #define clr(x) memset(x, 0, sizeof(x)) #define xx first #define yy second using namespace std; typedef pair<int, int> pii; typedef long long ll; const int inf = 0x3f3f3f3f; const ll INF = 0x3f3f3f3f3f3f3f3fll; //************************************************ const int maxn = 300005; struct Ed { int u, v, nx; Ed() {} Ed(int _u, int _v, int _nx) : u(_u), v(_v), nx(_nx) {} } E[maxn]; int G[maxn], edtot; void addedge(int u, int v) { E[++edtot] = Ed(u, v, G[u]); G[u] = edtot; } struct node { int dis, l, r, sz; ll key, tag_a, tag_b; int id; } heap[maxn]; int ndtot; ll hp[maxn], A[maxn], V[maxn]; int pre[maxn], root[maxn]; ll S[maxn], C[maxn]; void Push_down(int x) { if (heap[x].tag_a == 1 && heap[x].tag_b == 0) return; int l = heap[x].l, r = heap[x].r; heap[l].tag_a *= heap[x].tag_a, heap[l].tag_b = heap[l].tag_b * heap[x].tag_a + heap[x].tag_b; heap[r].tag_a *= heap[x].tag_a, heap[r].tag_b = heap[r].tag_b * heap[x].tag_a + heap[x].tag_b; heap[l].key = heap[l].key * heap[x].tag_a + heap[x].tag_b; heap[r].key = heap[r].key * heap[x].tag_a + heap[x].tag_b; heap[x].tag_a = 1, heap[x].tag_b = 0; return; } int merge(int x, int y) { if (!x) return y; if (!y) return x; Push_down(x), Push_down(y); if (heap[x].key > heap[y].key) swap(x, y); heap[x].r = merge(heap[x].r, y); heap[x].sz = heap[heap[x].l].sz + heap[heap[x].r].sz + 1; if (heap[heap[x].l].dis < heap[heap[x].r].dis) swap(heap[x].l, heap[x].r); heap[x].dis = heap[heap[x].r].dis + 1; return x; } int Stop[maxn], Peo[maxn]; int dep[maxn]; void solve(int x) { for (int i = G[x], y; i; i = E[i].nx) { dep[y = E[i].v] = dep[x] + 1; solve(y); root[x] = merge(root[x], root[y]); } Push_down(root[x]); while (root[x] && heap[root[x]].key < hp[x]) { Push_down(root[x]); Stop[heap[root[x]].id] = x; Peo[x]++; root[x] = merge(heap[root[x]].l, heap[root[x]].r); } if (root[x]) { Push_down(root[x]); if (A[x] == 0) heap[root[x]].tag_b = V[x], heap[root[x]].key += V[x]; else heap[root[x]].tag_a = V[x], heap[root[x]].key *= V[x]; } } int main() { int n, m; scanf("%d%d", &n, &m); rep(i, 1, n) scanf("%lld", hp + i); rep(i, 2, n) { scanf("%d%lld%lld", pre + i, A + i, V + i); addedge(pre[i], i); } rep(i, 1, m) { scanf("%lld%lld", S + i, C + i); heap[++ndtot] = (node) {0, 0, 0, 1, S[i], 1, 0, i}; root[C[i]] = merge(root[C[i]], ndtot); } solve(1); rep(i, 1, n) printf("%d\n", Peo[i]); rep(i, 1, m) printf("%d\n", Stop[i] ? dep[C[i]] - dep[Stop[i]] : dep[C[i]] + 1); }
View Code
相关文章推荐
- 北漂程序员创业记之把我留下二回家
- java的几种对象(PO,VO,DAO,BO,POJO)解释
- Windows 与 .net
- bzoj 4002: [JLOI2015]有意义的字符串
- 查看.NET Service Pack版本
- [Algorithm]Maze Prim算法与A*寻路算法(中)
- poj 2983 Is the Information Reliable?(差分约束)
- N-Queens 题解
- 【POJ 2243】Knight Moves
- js仿qq分组折叠效果
- linux下fdisk建盘
- 机器学习基石笔记-感知机
- [LeetCode]164. Maximum Gap
- jQuery13(相对元素的练习)
- 面试笔试杂项积累-leetcode 141-145
- fibonacci数列 取模
- python的正则表达式 re
- N-Queens II 经典问题:8皇后问题 题解
- 具备白名单、黑名单的Filter基类扩展
- theano中的logisticregression代码学习