数据结构 线段树 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 出来后 要把前面数过之后把分支清掉,重新数
思路:首先看到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; }
相关文章推荐
- 【2016-大连赛区网络赛-J】线段树,dfs(Weak Pair,hdu 5877)
- Weak Pair HDU - 5877 (dfs+线段树!!有根树!!)
- hdu 5877 Weak Pair dfs + 线段树(or树状数组)
- 数据结构 线段树 HDU 1754I Hate It(单点更新)
- hdu 1754 I Hate It(数据结构:线段树)
- HDU 4902 Nice boat(数据结构-线段树)
- HDU 4902 Nice boat(数据结构-线段树)
- hdu 1394 Minimum Inversion Number(数据结构:线段树)
- HDU5877 Weak Pair dfs + 线段树/树状数组 + 离散化
- ACM 数据结构 线段树 HDU 1540 Tunnel Warfare
- HDU 3308 LCIS 最长连续递增序列+数据结构+线段树+单点更新
- 线段树,数据结构,RMQ,分治法,最大和(Magician,HDU 5316)
- [ACM_数据结构] HDU 1166 敌兵布阵 线段树 或 树状数组
- HDU 1394 Minimum Inversion Number [线段树->单点更新]【数据结构】
- HDU 1166 数据结构-<线段树>
- 数据结构 线段树 HDU 2795Billboard(单点更新)
- HDU 1754 线段树+深搜 数据结构
- hdu 1166 敌兵布阵(数据结构:树状数组||线段树)
- HDU 1394 Minimum Inversion Number (数据结构-线段树)
- HDU—1754—I_Hate_It—【数据结构】【线段树】【单点更新】