您的位置:首页 > 理论基础 > 数据结构算法

HDU 5877 treap

2016-09-10 21:33 316 查看
点击打开链接

题意:很简单不说了

思路:就是根在向下更新的时候,将点压入,结束时弹出,每次询问比当前点小的个数#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=100010;
struct Node{
Node *ch[2];
int r,s,weight;
ll v;
Node(ll v):v(v){ch[0]=ch[1]=NULL;r=rand();s=1;weight=1;}
int cmp(ll x){
if(x==v) return -1;
return x<v? 0:1;
}
void maintain(){
s=weight;
if(ch[0]!=NULL) s+=ch[0]->s;
if(ch[1]!=NULL) s+=ch[1]->s;
}
};
void Rotate(Node* &o,int d){
Node* k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o;
o->maintain();k->maintain();o=k;
}
void Insert(Node* &o,int x){
if(o==NULL) o=new Node(x);
else{
if(x==o->v) o->weight++;
else{
int d=x<(o->v)? 0:1;
Insert(o->ch[d],x);
if(o->ch[d]->r>o->r) Rotate(o,d^1);
}
}
o->maintain();
}
void Remove(Node* &o,int x){
int d=o->cmp(x);
if(d==-1){
if(o->weight>1) o->weight--;
else{
Node* u=o;
if(o->ch[0]!=NULL&&o->ch[1]!=NULL){
int d2=(o->ch[0]->r>o->ch[1]->r?1:0);
Rotate(o,d2);Remove(o->ch[d2],x);
}else{
if(o->ch[0]==NULL) o=o->ch[1];
else o=o->ch[0];
delete u;
}
}
}else Remove(o->ch[d],x);
if(o!=NULL) o->maintain();
}
int Rank(Node* &o,ll x){
if(o==NULL) return 0;
int num=o->ch[0]==NULL?0:o->ch[0]->s;
if(x==o->v) return num+1;
else if(x<o->v) return Rank(o->ch[0],x);
else return Rank(o->ch[1],x)+num+o->weight;
}
Node *root;
ll A[maxn],ans,k;
vector<int>G[maxn];
int vis[maxn];
void dfs(int x){
if(A[x]==0) ans+=Rank(root,INF);
else ans+=Rank(root,k/A[x]);
Insert(root,A[x]);
for(unsigned int i=0;i<G[x].size();i++){
int t=G[x][i];
dfs(t);
}
Remove(root,A[x]);
}
int main(){
int T,n,u,v;
scanf("%d",&T);
while(T--){
scanf("%d%I64d",&n,&k);
root=NULL;
for(int i=0;i<=n;i++) G[i].clear(),vis[i]=0;
for(int i=1;i<=n;i++) scanf("%I64d",&A[i]);
for(int i=0;i<n-1;i++) scanf("%d%d",&u,&v),G[u].push_back(v),vis[v]=1;
int st;
for(int i=1;i<=n;i++) if(!vis[i]) st=i;
ans=0;
dfs(st);
printf("%I64d\n",ans);
}
return 0;
}
/*
100
10 15
1 2 3 4 5 6 7 8 9 10
1 2
2 8
2 9
1 3
3 4
3 6
4 5
4 7
5 10
10 15
1 2 2 4 5 6 7 8 9 10
1 2
2 8
2 9
1 3
3 4
3 6
4 5
4 7
5 10
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM 数据结构