HDU 5877 Weak Pair treap + dfs序
2016-09-11 09:59
435 查看
转载:http://www.itdadao.com/articles/c15a372922p0.html
题意:
给出一棵
题解:
最近学treap,发个题解
从根开始dfs,
用treap维护当前节点
然后就在treap上查询小于等于K/a[v]
之后把a[u]加到treap中, 退栈的时候把a[u]从treap中删除. 复杂度是nlogn的.
题意:
给出一棵
n个结点的树和一个数
k, 每个节点上有权值
??, 问有多少个有序对
(u,v) (u,v)满足
u是
v的祖先, a[u] * a[v] <=K;
题解:
最近学treap,发个题解
从根开始dfs,
用treap维护当前节点
uu到根的节点权值序列,
然后就在treap上查询小于等于K/a[v]
??的数的个数.
之后把a[u]加到treap中, 退栈的时候把a[u]从treap中删除. 复杂度是nlogn的.
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define ls i<<1 #define rs ls | 1 #define mid ((ll+rr)>>1) #define pii pair<int,int> #define MP make_pair typedef long long LL; const long long INF = 1e18+10; const double Pi = acos(-1.0); const int N = 1e5+10, M = 1e6+11, mod = 1e9+7, inf = 2e9; LL K,ans,a ; int n,size,root,head ,t; struct data{ int l,r,size,rnd,w; LL v; }tr ; void update(int k)//更新结点信息 { tr[k].size=tr[tr[k].l].size+tr[tr[k].r].size+tr[k].w; } void rturn(int &k) { int t=tr[k].l;tr[k].l=tr[t].r;tr[t].r=k; tr[t].size=tr[k].size;update(k);k=t; } void lturn(int &k) { int t=tr[k].r;tr[k].r=tr[t].l;tr[t].l=k; tr[t].size=tr[k].size;update(k);k=t; } void insert(int &k,LL x) { if(k==0) { size++;k=size; tr[k].size=tr[k].w=1;tr[k].v=x;tr[k].rnd=rand(); return; } tr[k].size++; if(tr[k].v==x)tr[k].w++; else if(x>tr[k].v) { insert(tr[k].r,x); if(tr[tr[k].r].rnd<tr[k].rnd)lturn(k); } else { insert(tr[k].l,x); if(tr[tr[k].l].rnd<tr[k].rnd)rturn(k); } } void del(int &k,LL x) { if(k==0)return; if(tr[k].v==x) { if(tr[k].w>1) { tr[k].w--;tr[k].size--;return; } if(tr[k].l*tr[k].r==0)k=tr[k].l+tr[k].r; else if(tr[tr[k].l].rnd<tr[tr[k].r].rnd) rturn(k),del(k,x); else lturn(k),del(k,x); } else if(x>tr[k].v) tr[k].size--,del(tr[k].r,x); else tr[k].size--,del(tr[k].l,x); } int query_rank(int k,LL x) { if(k==0)return 0; if(tr[k].v==x)return tr[tr[k].l].size+tr[k].w; else if(x>tr[k].v) return tr[tr[k].l].size+tr[k].w+query_rank(tr[k].r,x); else return query_rank(tr[k].l,x); } struct ss{int to,next;}e[N * 2]; void add(int u,int v) {e[t].next=head[u];e[t].to=v;head[u]=t++;} void dfs(int u,int fa) { LL limit = INF; if(a[u] != 0) limit = K/(a[u]); ans += (query_rank(root,limit)); insert(root,a[u]); for(int i = head[u]; i; i = e[i].next) { int to = e[i].to; if(to == fa) continue; dfs(to,u); } del(root,a[u]); } int d ; int main() { int T; scanf("%d",&T); while(T--) { size = 0; root = 0; memset(head,0,sizeof(head));t = 1; for(int i = 1; i < N; ++i) { tr[i].l = 0; tr[i].r = 0; d[i] = 0; } scanf("%d%lld",&n,&K); for(int i = 1; i <= n; ++i) scanf("%lld",&a[i]); for(int i = 1; i < n; ++i) { int u,v; scanf("%d%d",&u,&v); add(u,v);add(v,u); d[v]++; } int rt; for(int i = 1; i <= n; ++i) if(!d[i]) rt = i; ans = 0; dfs(rt,0); printf("%lld\n",ans); } return 0; }
相关文章推荐
- hdu 5877 Weak Pair dfs + 线段树(or树状数组)
- 【2016-大连赛区网络赛-J】线段树,dfs(Weak Pair,hdu 5877)
- Weak Pair HDU - 5877 (dfs+线段树!!有根树!!)
- 【33.18%】【hdu 5877】Weak Pair (3种解法)
- Weak Pair HDU - 5877
- Weak Pair HDU - 5877
- HDU 5877 Weak Pair(dfs+BIT)
- HDU 5877 [dfs序][线段树][序]
- hdu 5877 dfs+离散化+树状数组
- hdu 5877 Weak Pair(dfs+树状数组)
- HDU 5877 Weak Pair(dfs + 树状数组 + 离散化)
- hdu 5877 离散化+树状数组+dfs序
- hdu 5877 Weak Pair (树状树状 +dfs)
- HDU - 5877 Weak Pair (dfs+离散化+树状数组)
- HDU 5877 Weak Pair 【dfs】【树状数组】【离散化】
- 2016年ACM/ICPC 亚洲区域赛 大连站 1011 Weak Pair(现HDU 5877) 树状数组离散化+dfs
- HDU - 5877 Weak Pair —— 线段树 dfs序 离散化
- Weak Pair HDU - 5877 树状数组+离散化+DFS遍历
- HDU 5877 Weak Pair (dfs 树状数组 || dfs序 主席树)
- HDU 5877 treap