mirror of
https://github.com/Kiritow/OJ-Problems-Source.git
synced 2024-03-22 13:11:29 +08:00
Create 5877_angon823.cpp
From http://blog.csdn.net/angon823/article/details/52496420
This commit is contained in:
parent
33ff3e8cc9
commit
adc8a5096c
319
HDOJ/5877_angon823.cpp
Normal file
319
HDOJ/5877_angon823.cpp
Normal file
|
@ -0,0 +1,319 @@
|
|||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#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<vector>
|
||||
#include<memory.h>
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user