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

数据结构 线段树 hdu 5-8-7-7 Weak Pair 线段树+离散化

2016-09-11 19:36 429 查看
题意:T个测试样例,有n个节点,和一个数字K,输入n个数 a1,a2.........an,输入n-1个 u和v ,u是v的祖先,求满足a[ u ] * a[ v ]<=K的个数

思路:首先看到u,v 肯定是要建树的,而且v要与v的所有祖先进行比较,比较的时候,a[ u ]<=K / a[ v ] 满足这个的a[ u ] 都要数进来,所以要进行离散化。

然后建树,先序遍历树,然后用线段树去统计符合的个数,dfs 出来后 要把前面数过之后把分支清掉,重新数

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const ll maxn=100010;
ll k,a[maxn],b[maxn<<1],ans;
int n,siz;
int sum[maxn<<3];
int head[maxn],top;

void PushUp(ll rt){
sum[rt]=sum[rt<<1] + sum[rt<<1|1];
}
void build(ll l,ll r,ll rt)
{
if(l==r){
sum[rt]=0;
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
void update(ll p,ll ss,ll l,ll r,ll rt){
//p要改的位置,ss为数值
if(l==r){
sum[rt]+=ss;
return ;
}
int m=(l+r)>>1;
if(p<=m) update(p,ss,lson);
else update(p,ss,rson);
PushUp(rt);
}
ll query(ll L,ll R,ll l,ll r,ll rt){
//询问L,R之间
if(L<=l && r<=R){
return sum[rt];
}
int m=(l+r)>>1;
int ret=0;
if(L<=m) ret+=query(L,R,lson);
if(R>m) ret+=query(L,R,rson);
return ret;
}
//-------------------------
struct Edge{
int to,from;
}edge[maxn<<1];

void into(){
memset(head,-1,sizeof(head));
memset(sum,0,sizeof(sum));
top=0;ans=0;
}
void add(int u,int v){
edge[top].to=v;
edge[top].from=head[u];
head[u]=top++;
}
void dfs(int root)
{
int l=lower_bound(b+1,b+siz+1,k/a[root])-b;
ans+= query(1,l,1,siz,1);
int pos=lower_bound(b+1,b+siz+1,a[root])-b;
update(pos,1,1,siz,1);
for(int i=head[root];i!=-1;i=edge[i].from)
{
int son=edge[i].to;
dfs(son);
}
update(pos,-1,1,siz,1);
}
int main()
{
int T;int cas=1;
scanf("%d",&T);
while(T--){
scanf("%d%I64d",&n,&k);
into();
int cnt=1;int root=0;
for(int i=1;i<=n;i++){
scanf("%I64d",&a[i]);
b[cnt++]=a[i];
}
for(int i=1;i<=n;i++)
b[cnt++]=k/a[i];
//离散化
sort(b+1,b+cnt);
siz=unique(b+1,b+cnt)-(b+1);
build(1,siz,1);
int u,v;
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
if(i==1) root=u;
if(root==v) root=u;
}

dfs(root);

printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: