HDU 5877 Weak Pair (dfs 树状数组 || dfs序 主席树)
来源:互联网 发布:淘宝买gtx1080截图 编辑:程序博客网 时间:2024/06/05 16:16
题意:给你一颗树,每个节点有一个权值,给你一个k,问你满足a[u]*a[v] <= k的个数。(u是v的祖先)
思路:做的时候看到u和v又是子树关系,想当然就是dfs序啦,然后变成a[v]<=k/a[u], 这样枚举每一个节点u,计算子
树中<=k/a[u]的节点个数,这一步可以用主席树求(类似于:点开),所以直接敲了dfs序+主席树。。
其实这题有简单做法,我们可以在dfs整棵树过程中计算每个点作为儿子节点的贡献,
贡献即为其祖先节点u, k/a[u] >= a[v]的个数。
因此可以用树状数组维护从根节点开始的k/ai值,遍历到某个节点时将该节点加入BIT,遍历结束时从BIT中删除,这
样对于每个节点,BIT中存的都是他的祖先。
因为数据比较大,所以离散化是必须的。
树状数组代码:
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 2e5+5;ll a[maxn], Hash[maxn], k, ans;vector<int> g[maxn];int n, d, du[maxn], tree[maxn];int lowbit(int x){ return x&(-x);}void update(int pos, int val){ while(pos < maxn) { tree[pos] += val; pos += lowbit(pos); }}int query(int pos){ int res = 0; while(pos) { res += tree[pos]; pos -= lowbit(pos); } return res;}void dfs(int u){ int x = lower_bound(Hash+1, Hash+1+d, a[u])-Hash; ans += query(maxn-1)-query(x-1); int y = lower_bound(Hash+1, Hash+1+d, k/a[u])-Hash; update(y, 1); for(int i = 0; i < g[u].size(); i++) { int v = g[u][i]; dfs(v); } update(y, -1);}int main(void){ int _; cin >> _; while(_--) { memset(tree, 0, sizeof(tree)); memset(du, 0, sizeof(du)); scanf("%d%lld", &n, &k); for(int i = 0; i <= n; i++) g[i].clear(); for(int i = 1; i <= n; i++) { scanf("%lld", &a[i]); Hash[i] = a[i]; Hash[i+n] = k/a[i]; } sort(Hash+1, Hash+1+2*n); d = unique(Hash+1, Hash+1+2*n)-Hash-1; for(int i = 1; i < n; i++) { int u, v; scanf("%d%d", &u, &v); g[u].push_back(v); du[v]++; } int tRoot; for(int i = 1; i <= n; i++) if(!du[i]) { tRoot = i; break; } ans = 0; dfs(tRoot); printf("%lld\n", ans); } return 0;}
#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5+5;vector<int> g[maxn];int n, a[maxn], in[maxn*4], out[maxn*4], fa[maxn*4], tot1, tot2;int lson[maxn<<5], rson[maxn<<5], sum[maxn<<5];int T[maxn], Hash[maxn];int cb[maxn], cur, d;ll k;int build(int l, int r){ int rt = ++tot2; sum[rt] = 0; if(l < r) { int mid = (l+r)/2; lson[rt] = build(l, mid); rson[rt] = build(mid+1, r); } return rt;}int update(int pre, int l, int r, int x){ int rt = ++tot2; lson[rt] = lson[pre], rson[rt] = rson[pre], sum[rt] = sum[pre]+1; if(l < r) { int mid = (l+r)/2; if(x <= mid) lson[rt] = update(lson[pre], l, mid, x); else rson[rt] = update(rson[pre], mid+1, r, x); } return rt;}int query(int u, int v, int l, int r, int k){ if(l >= r) return sum[v]-sum[u]; int mid = (l+r)/2; int ans = 0; if(k <= mid) ans += query(lson[u], lson[v], l, mid, k); else { ans += sum[lson[v]]-sum[lson[u]]; ans += query(rson[u], rson[v], mid+1, r, k); } return ans;}void dfs(int u, int pre){ int x = lower_bound(Hash+1, Hash+1+d, a[u])-Hash; T[cur] = update(T[cur-1], 1, d, x); cur++; in[u] = ++tot1; fa[u] = pre; for(int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if(v != pre) dfs(v, u); } out[u] = tot1;}int main(void){ int _; cin >> _; while(_--) { tot1 = tot2 = 0; memset(cb, 0, sizeof(cb)); for(int i = 0; i < maxn; i++) g[i].clear(); scanf("%d%lld", &n, &k); for(int i = 1; i <= n; i++) scanf("%d", &a[i]), Hash[i] = a[i]; sort(Hash+1, Hash+1+n); d = unique(Hash+1, Hash+1+n)-Hash-1; T[0] = build(1, d); for(int i = 1; i < n; i++) { int u, v; scanf("%d%d", &u, &v); g[u].push_back(v); cb[v]++; } int tRoot; for(int i = 1; i <= n; i++) if(!cb[i]) { tRoot = i; break; } cur = 1; dfs(tRoot, 0); ll ans = 0; for(int i = 1; i <= n; i++) { ll des = k/a[i]; int x = upper_bound(Hash+1, Hash+1+d, des)-Hash-1; ans += query(T[in[i]], T[out[i]], 1, d, x); } printf("%lld\n", ans); } return 0;}
阅读全文
1 0
- HDU 5877 Weak Pair (dfs 树状数组 || dfs序 主席树)
- HDU 5877 Weak Pair 树状数组 + DFS
- HDU 5877 Weak Pair dfs序 + 树状数组 + 离散化
- hdu 5877 Weak Pair(dfs+树状数组)
- HDU 5877 Weak Pair(dfs + 树状数组 + 离散化)
- hdu 5877 Weak Pair(树状数组 + dfs + 离散化)
- HDU 5877 Weak Pair 【dfs】【树状数组】【离散化】
- hdu 5877 Weak Pair dfs + 线段树(or树状数组)
- hdu 5877 Weak Pair (树状树状 +dfs)
- hdu5877 Weak Pair 【树状数组+dfs】
- hdu5877 Weak Pair(DFS+树状数组)
- HDU5877 Weak Pair(树状数组+dfs)
- HDU 5877 Weak Pair treap + dfs序
- HDU5877 Weak Pair dfs + 线段树/树状数组 + 离散化
- 2016 大连网络赛 HDU 5877 Weak Pair (DFS + 树状数组 + 离散化)
- HDU-5877-Weak Pair【树状数组】【离散化】【DFS】【2016大连网络】【好题】
- HDU 5877 Weak Pair(离散化+dfs+树状数组) 大连区域网络赛
- HDU 5877 Weak Pair(dfs+BIT)
- LEETCODE 48 672. Bulb Switcher II
- Javaweb之EL表达式
- Windows程序设计-窗口和消息
- Android的Cursor的close方法不调用会不会造成内存泄露
- 超简单!Linux下FTP服务器的安装和配置(基于Ubuntu)
- HDU 5877 Weak Pair (dfs 树状数组 || dfs序 主席树)
- svm+hog 训练,检测手写数字
- Asp.net MVC中ViewData与ViewBag的使用方法
- MySQL半同步复制--RUN_HOOK
- 0-1背包问题
- tomcat+nginx+redis实现均衡负载、session共享(二)
- 损失函数
- HDU -- 6188 Duizi and Shunzi 【思维】
- 33 Three.js的材质THREE.MeshBasicMaterial