diff --git a/HDOJ/5877_angon823.cpp b/HDOJ/5877_angon823.cpp new file mode 100644 index 0000000..9e9b88c --- /dev/null +++ b/HDOJ/5877_angon823.cpp @@ -0,0 +1,319 @@ +#include +#include +#define MAXN 200005 +int cnt = 1, rt = 0; +int Add[MAXN]; + +struct Tree{ + long long key; + int num, size, fa, son[2]; +}T[MAXN]; + +inline void PushUp(int x) +{ + T[x].size = T[T[x].son[0]].size + T[T[x].son[1]].size + T[x].num; +} + +inline void PushDown(int x) +{ + if (Add[x]) + { + if (T[x].son[0]) + { + T[T[x].son[0]].key += Add[x]; + Add[T[x].son[0]] += Add[x]; + } + if (T[x].son[1]) + { + T[T[x].son[1]].key += Add[x]; + Add[T[x].son[1]] += Add[x]; + } + Add[x] = 0; + } +} + +inline int Newnode(long long key, int fa) //新建一个节点并返回 +{ + ++cnt; + T[cnt].key = key; + T[cnt].num = T[cnt].size = 1; + T[cnt].fa = fa; + T[cnt].son[0] = T[cnt].son[1] = 0; + return cnt; +} + +inline void Rotate(int x, int p) //0左旋 1右旋 +{ + int y = T[x].fa; + PushDown(y); + PushDown(x); + T[y].son[!p] = T[x].son[p]; + T[T[x].son[p]].fa = y; + T[x].fa = T[y].fa; + if (T[x].fa) + T[T[x].fa].son[T[T[x].fa].son[1] == y] = x; + T[x].son[p] = y; + T[y].fa = x; + PushUp(y); + PushUp(x); +} + +void Splay(int x, int To) //将x节点移动到To的子节点中 +{ + while (T[x].fa != To) + { + if (T[T[x].fa].fa == To) + Rotate(x, T[T[x].fa].son[0] == x); + else + { + int y = T[x].fa, z = T[y].fa; + int p = (T[z].son[0] == y); + if (T[y].son[p] == x) + Rotate(x, !p), Rotate(x, p); //之字旋 + else + Rotate(y, p), Rotate(x, p); //一字旋 + } + } + if (To == 0) rt = x; +} + +int GetPth(int p, int To) //返回第p小的节点 并移动到To的子节点中 +{ + if (!rt || p > T[rt].size) return 0; + int x = rt; + while (x) + { + PushDown(x); + if (p >= T[T[x].son[0]].size + 1 && p <= T[T[x].son[0]].size + T[x].num) + break; + if (p > T[T[x].son[0]].size + T[x].num) + { + p -= T[T[x].son[0]].size + T[x].num; + x = T[x].son[1]; + } + else + x = T[x].son[0]; + } + Splay(x, 0); + return x; +} + +int Find(long long key) //返回值为key的节点 若无返回0 若有将其转移到根处 +{ + if (!rt) return 0; + int x = rt; + while (x) + { + PushDown(x); + if (T[x].key == key) break; + x = T[x].son[key > T[x].key]; + } + if (x) Splay(x, 0); + return x; +} + +int Prev() //返回根节点的前驱 非重点 +{ + if (!rt || !T[rt].son[0]) return 0; + int x = T[rt].son[0]; + while (T[x].son[1]) + { + PushDown(x); + x = T[x].son[1]; + } + Splay(x, 0); + return x; +} + +int Succ() //返回根结点的后继 非重点 +{ + if (!rt || !T[rt].son[1]) return 0; + int x = T[rt].son[1]; + while (T[x].son[0]) + { + PushDown(x); + x = T[x].son[0]; + } + Splay(x, 0); + return x; +} + +void Insert(long long key) //插入key值 +{ + if (!rt) + rt = Newnode(key, 0); + else + { + int x = rt, y = 0; + while (x) + { + PushDown(x); + y = x; + if (T[x].key == key) + { + T[x].num++; + T[x].size++; + break; + } + T[x].size++; + x = T[x].son[key > T[x].key]; + } + if (!x) + x = T[y].son[key > T[y].key] = Newnode(key, y); + Splay(x, 0); + } +} + +void Delete(long long key) //删除值为key的节点1个 +{ + int x = Find(key); + if (!x) return; + if (T[x].num>1) + { + T[x].num--; + PushUp(x); + return; + } + int y = T[x].son[0]; + while (T[y].son[1]) + y = T[y].son[1]; + int z = T[x].son[1]; + while (T[z].son[0]) + z = T[z].son[0]; + if (!y && !z) + { + rt = 0; + return; + } + if (!y) + { + Splay(z, 0); + T[z].son[0] = 0; + PushUp(z); + return; + } + if (!z) + { + Splay(y, 0); + T[y].son[1] = 0; + PushUp(y); + return; + } + Splay(y, 0); + Splay(z, y); + T[z].son[0] = 0; + PushUp(z); + PushUp(y); +} + +int GetRank(long long key) //获得值<=key的节点个数 +{ + if (!Find(key)) + { + Insert(key); + int tmp = T[T[rt].son[0]].size; + Delete(key); + return tmp; + } + else + return T[T[rt].son[0]].size + T[rt].num; +} + +void Delete(int l, int r) //删除值在[l, r]中的所有节点 l!=r +{ + if (!Find(l)) Insert(l); + int p = Prev(); + if (!Find(r)) Insert(r); + int q = Succ(); + if (!p && !q) + { + rt = 0; + return; + } + if (!p) + { + T[rt].son[0] = 0; + PushUp(rt); + return; + } + if (!q) + { + Splay(p, 0); + T[rt].son[1] = 0; + PushUp(rt); + return; + } + Splay(p, q); + T[p].son[1] = 0; + PushUp(p); + PushUp(q); +} +#define MAX 100005 +#include +#include +using namespace std; +int v[MAX]; +int N; +long long K; +long long res = 0; +struct Edge +{ + int b; + int next; +}edge[MAX]; +int edgeCnt = 1; +int adj[MAX]; +void AddEdge(int a, int b) +{ + edge[edgeCnt].b = b; + edge[edgeCnt].next = adj[a]; + adj[a] = edgeCnt++; +} +void Search(int now) +{ + res += GetRank(K / v[now]); + Insert(v[now]); + for(int p = adj[now]; p; p = edge[p].next) + { + Search(edge[p].b); + } + Delete(v[now]); +} +int in[MAX]; +int main() { + int T; + while(~scanf("%d", &T)) + { + int i; + int a, b; + for (; T; T--) + { + scanf("%d%lld", &N, &K); + memset(adj, 0, (N + 1) * sizeof(int)); + memset(in, 0, (N + 1) * sizeof(int)); + edgeCnt = 1; + for (i = 1; i <= N; i++) + { + scanf("%d", &v[i]); + } + for (i = 1; i < N; i++) + { + scanf("%d%d", &a, &b); + in[b]++; + AddEdge(a, b); + } + for (i = 1; i <= N; i++) + { + if (in[i] == 0) + { + break; + } + } + cnt = 1, rt = 0; + res = 0; + Search(i); + printf("%lld\n", res); + } + } + return 0; +}