hdu 5877 Weak Pair dfs + 线段树(or树状数组)
来源:互联网 发布:买家怎么取消农村淘宝 编辑:程序博客网 时间:2024/06/07 06:01
// hdu 5877 Weak Pair dfs + 线段树(or树状数组)//// 题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5877//// 题目大意:// n个节点到有根树,u是v的祖先,每个节点有个权值a[u].求// a[u] * a[v] <= k的有序对的数量。//// 解答:// 我们可以进行dfs,这样可以将当前节点和它之前到祖先关联// 起来,即,在它之前到一定是它到祖先。这样对于当前节点u// 我们查找小于等于k/a[u]到u到祖先的个数x,将x累加即可得// 到答案,这里我们可以用线段树或者树状数组。将a[u]的值// 映射到线段树中,由于a[u]比较大,离散化一下,即可。//// 感悟:// 这题,仔细想来,还是可以做的,只是真的好久没写代码了,// 都生疏了,心中有着一丝到恐惧,现在慢慢捡起来,有段日子// 觉得代码很恶心(我错了),但每次捡起来,都觉得很有趣,// 这次,我将不打算放弃,将代码进行到底。内心成长。加油#include <cstdio>#include <iostream>#include <cstring>#include <stack>#include <queue>#include <algorithm>using namespace std;typedef long long ll;const int MAXN = 1e5 + 8;int a[MAXN];int b[MAXN];int in[MAXN];int cnt;ll sum = 0;int n;ll k;vector<int> g[MAXN];struct SegmentTree{#define lson(x) (x << 1)#define rson(x) (x << 1 | 1) int sum[MAXN << 2]; int ql,qr; void setq(int l,int r){ ql = l; qr = r; } void setp(int l){ ql = l; } void init(){ memset(sum,0,sizeof(sum)); } void push_up(int rt){ sum[rt] = sum[lson(rt)] + sum[rson(rt)]; } void modify(int rt,int v,int L,int R){ if (L == R){ sum[rt] += v; return ; } int M = (L + R) >> 1; if (ql <= M) modify(lson(rt),v,L,M); else modify(rson(rt),v,M+1,R); push_up(rt); } int query(int rt,int L,int R){ if (ql <= L && R <= qr){ return sum[rt]; } int M = (L + R) >> 1; int res = 0; if (ql <= M) res += query(lson(rt),L,M); if (qr > M) res += query(rson(rt),M+1,R); return res; }}it;void dfs(int u,int fa){ it.setq(1,upper_bound(b + 1,b + cnt + 1,k / a[u]) - b - 1); // 查找区间[1.k/a[u]) // cout << k / a[u] << "----" << it.qr << // "----" << it.query(1,1,cnt) << endl; sum += it.query(1,1,cnt); it.setp(lower_bound(b + 1,b + cnt + 1,a[u])- b); // 找到a[u]的位置 // cout << "before" << pos << " " << u << " " << a[u] << endl; // cout << "sum: " << sum << endl; if (!(int)g[u].size()) return; it.modify(1,1,1,cnt); // 插入 for (int i = 0;i < g[u].size();i ++){ if (g[u][i] == fa) continue; dfs(g[u][i],u); } it.setp(lower_bound(b + 1,b + cnt + 1,a[u])- b); it.modify(1,-1,1,cnt); // 删除(因为递归回来的时候,这个节点贡献值完 // 毕,即已经遍历完以它为父节点到子树)}int main(){ int t; scanf("%d",&t); while(t--){ scanf("%d%I64d\n",&n,&k); for (int i = 1;i <= n;i ++) // 初始化 g[i].clear(); sum = 0; it.init(); for (int i = 1;i <= n;i ++){ scanf("%d", a + i); b[i] = a[i]; } sort(b + 1,b + n + 1); // 排序,离散化的准备 cnt = unique(b + 1,b + n + 1) - b - 1; // 离散化 memset(in,0,sizeof(in)); for (int i = 1;i < n;i ++){ int u,v; scanf("%d%d",&u,&v); g[u].push_back(v); in[v]++; // 入度为0到点为根 } int rt = 0; for (int i = 1;i <= n;i ++){ if (!in[i]){ rt = i; break; } } dfs(rt,-1); printf("%I64d\n",sum); } return 0;}
0 0
- hdu 5877 Weak Pair dfs + 线段树(or树状数组)
- HDU 5877 Weak Pair 树状数组 + DFS
- hdu 5877 Weak Pair(dfs+树状数组)
- hdu 5877 Weak Pair(树状数组 + dfs + 离散化)
- HDU5877 Weak Pair dfs + 线段树/树状数组 + 离散化
- hdu 5877 Weak Pair(树状数组)
- HDU 5877 Weak Pair(dfs + 树状数组 + 离散化)
- HDU 5877 Weak Pair 【dfs】【树状数组】【离散化】
- HDU 5877 Weak Pair dfs序 + 树状数组 + 离散化
- HDU 5877 Weak Pair (dfs 树状数组 || dfs序 主席树)
- 2016 大连网络赛 HDU 5877 Weak Pair (DFS + 树状数组 + 离散化)
- [HDU 8577] Weak Pair (DFS+线段树)
- HDU-5877-Weak Pair(离散+树状数组)
- hdu 5877 Weak Pair (树状树状 +dfs)
- 【2016-大连赛区网络赛-J】线段树,dfs(Weak Pair,hdu 5877)
- HDU-5877-Weak Pair【树状数组】【离散化】【DFS】【2016大连网络】【好题】
- HDU 5877 Weak Pair(离散化+dfs+树状数组) 大连区域网络赛
- hdu5877 Weak Pair 【树状数组+dfs】
- java and python学习——第一周leetcode刷题
- 解决Idea创建maven-archetype-webapp项目无java目录的问题
- java观察着observer模式---商品价格变动通知客户
- 关于python里面的对齐
- 短信发送器
- hdu 5877 Weak Pair dfs + 线段树(or树状数组)
- LeetCode 24. Swap Nodes in Pairs
- 手游服务端开发基础概念扫盲篇
- java多线程:创建、join方法
- FTP 限制用户只访问HOME目录
- chrome 中的console 下无法使用jquery选择器
- Android操作GPIO
- mac 编译《unix网络编程》 的libunp.a
- 《民主的细节》摘录