CF 696E ...Wait for it... 链剖练手题
来源:互联网 发布:乐清市知临学校招聘 编辑:程序博客网 时间:2024/05/23 17:13
题目大意
给定一颗
解题思路
一道链剖的裸题!
对于一个点上的物品,它们权值的大小关系是确定的。那么我们只要在一开始把物品都丢到节点
程序
//YxuanwKeith#include <cstring>#include <cstdio>#include <algorithm>#include <vector>using namespace std;typedef long long LL;const int MAXN = 1e5 + 5;const LL Inf = 1e15 + 7;struct Node { LL Val; int Num; Node (LL val, int num){Val = val, Num = num;} Node (){}};struct Tree { LL add; int Num; Node Min;} Tr[MAXN * 4];vector<int> P[MAXN];int N, M, Q, time, Bel[MAXN], Size[MAXN], MSon[MAXN], L[MAXN], R[MAXN], Deep[MAXN], Pre[MAXN], Top[MAXN];int tot, Last[MAXN], Go[MAXN * 2], Next[MAXN * 2];void Link(int u, int v) { Next[++ tot] = Last[u], Last[u] = tot, Go[tot] = v;}Node Min(Node A, Node B) { if (A.Val < B.Val) return A; if (A.Val > B.Val) return B; if (A.Num < B.Num) return A; return B;}void Basis(int Now, int Fa) { Size[Now] = 1, MSon[Now] = 0; Pre[Now] = Fa, Deep[Now] = Deep[Fa] + 1; for (int p = Last[Now]; p; p = Next[p]) { int v = Go[p]; if (v == Fa) continue; Basis(v, Now); Size[Now] += Size[v]; if (Size[v] > Size[MSon[Now]]) MSon[Now] = v; }}void Promote(int Now, int top) { if (!Now) return; L[Now] = ++ time, Bel[time] = Now; Top[Now] = top; Promote(MSon[Now], top); for (int p = Last[Now]; p; p = Next[p]) { int v = Go[p]; if (v == Pre[Now] || v == MSon[Now]) continue; Promote(v, v); } R[Now] = time;}bool Cmp(int A, int B) { return A > B;}Node Get(int Now) { if (P[Now].empty()) return Node(Inf, Bel[Now]); return Node(P[Now].back(), Bel[Now]);}Node Up(Node A, LL add) { A.Val += add; return A;}void MakeTag(int Now, LL add) { Tr[Now].add += add;}void Push(int Now, int l, int r) { if (l != r) { int Mid = (l + r) >> 1; MakeTag(Now * 2, Tr[Now].add); MakeTag(Now * 2 + 1, Tr[Now].add); Tr[Now].Min = Min(Up(Tr[Now * 2].Min, Tr[Now * 2].add), Up(Tr[Now * 2 + 1].Min, Tr[Now * 2 + 1].add)); Tr[Now].add = 0; }}void Modify(int Now, int l, int r, int lx, int rx, LL add) { Push(Now, l, r); if (l == lx && r == rx) { MakeTag(Now, add); return; } int Mid = (l + r) >> 1; if (rx <= Mid) Modify(Now * 2, l, Mid, lx, rx, add); else if (lx > Mid) Modify(Now * 2 + 1, Mid + 1, r, lx, rx, add); else { Modify(Now * 2, l, Mid, lx, Mid, add); Modify(Now * 2 + 1, Mid + 1, r, Mid + 1, rx, add); } Tr[Now].Min = Min(Up(Tr[Now * 2].Min, Tr[Now * 2].add), Up(Tr[Now * 2 + 1].Min, Tr[Now * 2 + 1].add));}void Build(int Now, int l, int r) { if (l == r) { Tr[Now].Min = Get(l); return; } int Mid = (l + r) >> 1; Build(Now * 2, l, Mid), Build(Now * 2 + 1, Mid + 1, r); Tr[Now].Min = Min(Tr[Now * 2].Min, Tr[Now * 2 + 1].Min);}Node Ask(int Now, int l, int r, int lx, int rx) { Push(Now, l, r); if (l == lx && r == rx) return Up(Tr[Now].Min, Tr[Now].add); int Mid = (l + r) >> 1; if (rx <= Mid) return Up(Ask(Now * 2, l, Mid, lx, rx), Tr[Now].add); else if (lx > Mid) return Up(Ask(Now * 2 + 1, Mid + 1, r, lx, rx), Tr[Now].add); else return Up(Min(Ask(Now * 2, l, Mid, lx, Mid), Ask(Now * 2 + 1, Mid + 1, r, Mid + 1, rx)), Tr[Now].add);}int Ask(int u, int v) { Node Ans = Node(Inf, 0); while (Top[u] != Top[v]) { if (Deep[Top[u]] < Deep[Top[v]]) swap(u, v); Ans = Min(Ans, Ask(1, 1, N, L[Top[u]], L[u])); u = Pre[Top[u]]; } if (L[u] > L[v]) swap(u, v); Ans = Min(Ans, Ask(1, 1, N, L[u], L[v])); return Ans.Num;}void Del(int Now, int l, int r, int Side) { Push(Now, l, r); if (l == r) { P[l].pop_back(); Tr[Now].Min = Get(l); return; } int Mid = (l + r) >> 1; if (Side <= Mid) Del(Now * 2, l, Mid, Side); else Del(Now * 2 + 1, Mid + 1, r, Side); Tr[Now].Min = Min(Up(Tr[Now * 2].Min,Tr[Now * 2].add), Up(Tr[Now * 2 + 1].Min, Tr[Now * 2 + 1].add));}void Query(int u, int v, int Lim) { static int D[MAXN]; int top = 0; for (int i = 1; i <= Lim; i ++) { int Now = L[Ask(u, v)]; if (!Now) break; D[++ top] = P[Now].back(); Del(1, 1, N, Now); } printf("%d ", top); for (int i = 1; i <= top; i ++) printf("%d ", D[i]); printf("\n");}void Prepare() { Basis(1, 0); Promote(1, 1);}int main() { scanf("%d%d%d", &N, &M, &Q); for (int i = 1; i < N; i ++) { int u, v; scanf("%d%d", &u, &v); Link(u, v), Link(v, u); } Prepare(); for (int i = 1; i <= M; i ++) { int Val; scanf("%d", &Val); P[L[Val]].push_back(i); } for (int i = 1; i <= N; i ++) sort(P[i].begin(), P[i].end(), Cmp); Build(1, 1, N); for (int i = 1; i <= Q; i ++) { int Ord; scanf("%d", &Ord); if (Ord == 1) { int u, v, Lim; scanf("%d%d%d", &u, &v, &Lim); Query(u, v, Lim); } else { int u, add; scanf("%d%d", &u, &add); Modify(1, 1, N, L[u], R[u], add); } }}
1 0
- CF 696E ...Wait for it... 链剖练手题
- 【Codeforces696E】...Wait for it...
- CF 212E. IT Restaurants
- CF 616F Expensive Strings 用到fail链性质的SAM练手题
- CF div #151 E题
- cf-e
- CF 13E Holes 【块状链表】
- CF 459E && 市赛I题
- Wait for
- Go for 练手
- e-Government CF 163E
- e-Government CF 163E
- cf 163e e-Government
- CF 208E
- CF #148 DIV2 E
- CF 145E
- CF 121E
- CF 338E Optimize!
- js通过key-value取值
- 自己动手编写仿QQ的app -1注册界面by sdust iot zhl
- Interesting drink--二分
- poj 1260 Pearls
- HDU 5861 Road(线段树)
- CF 696E ...Wait for it... 链剖练手题
- mysql远程可登录,本地无法登陆问题
- 使用strace, ltrace寻找故障原因的线索
- 哈哈,我也开通了博客
- CodeForces 686B Little Robber Girl's Zoo
- QT对象模型和一个小细节
- C++ 引用的作用和用法
- poj 1159 Palindrome
- Deep Residual Network学习(一)