HDU 5877 Weak Pair(2016 ACM/ICPC Asia Regional Dalian Online)
来源:互联网 发布:句读知不知是什么意思 编辑:程序博客网 时间:2024/05/01 12:49
题目大意
给你一个树,问你这棵树有多少对Weak Pair(一个对(u,v)成立当且仅当u是v的祖先并且
av∗au<=k
题目分析
对于一个棵树来说最容易想到的就是dfs遍历这棵树了吧!!假如说现在遍历到v节点,那么很明显之前遍历过的一定是u的祖先,那么我们就可以进行查找Weak Pair了,对于当前节点u对应的value值我们需要找到所有父亲节点中值小于k/value的节点个数,那么很明显对于父亲节点的值我们需要进行存储,但是父亲节点的值很大,因此我们需要离散化,为了快速查找父亲节点中值小于k/value的节点个数我们可以用线段树或者树状数组进行处理,进行线段树的单点更新以及区间查询即可。
我自己写这道题的时候遇到的一些问题在这里说一下:1.因为要进行离散化,所以需要加value和k/value存储下来,注意k/value可能超int,因此需要用long long保存。2.因为线段树所对应的数组大小一定要注意开大一点,因为value和k/value都存储下来之后相当于原来大小的2倍了,不开大可能会超时(我就超时了一次)。3.根节点不一定是1,因此在输入边的时候我们可以用一个数组来存一下每个点的入度,入度为0的点才是根节点。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 2e5+5;typedef long long LL;#define mid (L+R)/2#define lson o<<1, L, mid#define rson o<<1|1, mid+1, RLL a[maxn], b[maxn], head[maxn], degree[maxn], sum[maxn<<2];LL T, N, k, ans, tot;struct Edge{ //邻接表 int to,next;}e[maxn];void update(int o,int L,int R,int v,int cnt){ //更新 if(L == R){ sum[o] += cnt; return ; } if(v <= mid) update(lson, v, cnt); else update(rson, v, cnt); sum[o] = sum[o<<1] + sum[o<<1|1];}LL query(int o,int L,int R,int l,int r){ //查询 if(l <= L && R <= r) return sum[o]; LL ret = 0; if(l <= mid) ret += query(lson, l, r); if(r > mid) ret += query(rson, l, r); return ret;}void addedge(int from, int to){ e[tot].to = to; e[tot].next = head[from]; head[from] = tot++;}int BS(LL b[], int n, LL val){ //二分查找 int left = 1, right = n; while(left <= right){ int m = (left + right)/2; if(b[m] == val) return m; else if(b[m] < val) left = m+1; else right = m-1; } return -1;}void dfs(int u){ ans += query(1, 1, 2*N, 1, BS(b, 2*N, k/a[u])); int x = BS(b, 2*N, a[u]); update(1, 1, 2*N, x, 1); for(int i = head[u]; i != -1; i = e[i].next){ int v = e[i].to; dfs(v); } update(1, 1, 2*N, x, -1);}void init(){ tot = ans = 0; memset(degree, 0, sizeof(degree)); memset(sum, 0, sizeof(sum)); memset(head, -1, sizeof(head));}int main(){ scanf("%I64d", &T); while(T--){ init(); scanf("%I64d%I64d", &N, &k); for(int i = 1; i <= N; i++){ scanf("%I64d", &a[i]); b[i] = a[i]; b[i+N] = k/a[i]; } sort(b+1, b+1+2*N); int from, to; for(int i = 1; i < N; i++){ scanf("%d%d", &from, &to); addedge(from, to); degree[to]++; } for(int i = 1; i <= N; i++) if(!degree[i]){ dfs(i); break; } printf("%I64d\n", ans); } return 0;}
0 0
- HDU 5877 2016 ACM/ICPC Asia Regional Dalian Online 1010 Weak Pair
- HDU 5877 Weak Pair 2016 ACM/ICPC Asia Regional Dalian Online(树状数组+离散化)
- HDU 5877 Weak Pair(2016 ACM/ICPC Asia Regional Dalian Online)
- HDU 5877 Weak Pair(离散化+dfs+树状数组)——2016 ACM/ICPC Asia Regional Dalian Online
- 2016 ACM/ICPC Asia Regional Dalian Online 1010 Weak Pair 离散化+树状数组
- hdu 5877/ 2016 ACM/ICPC Dalian Online 1010 Weak Pair
- hdu 5875 2016 ACM/ICPC Asia Regional Dalian Online 1008
- HDU 5875 Function 2016 ACM/ICPC Asia Regional Dalian Online
- HDU 5875 Function 2016 ACM/ICPC Asia Regional Dalian Online
- hdu 5875 2016 ACM/ICPC Asia Regional Dalian Online 1008
- 2016 ACM/ICPC Asia Regional Dalian Online
- 2016 ACM/ICPC Asia Regional Dalian Online
- 2016 Asia Regional Dalian Online 1010 Weak Pair
- 2016 ACM/ICPC Dalian Online-1010 Weak Pair
- 2016 ACM/ICPC Asia Regional Dalian Online Sparse Graph(BFS)
- 2016 ACM/ICPC Asia Regional Dalian Online Football Games
- 2016 ACM/ICPC Asia Regional Dalian Online Friends and Enemies
- 2016 ACM/ICPC Asia Regional Dalian Online 1008 Function
- ubuntu下安装JDK
- 向用户提问“现在正在下雨吗?”提示用户输入Y或N若输入Y显示“现在正在下雨”,输入N显示“现在没有下雨”否则继续提问
- LeetCode 14 -- Longest Common Prefix
- 【JAVA】JAVA 数据存储
- TCP/IP四层模型和OSI七层模型的概念
- HDU 5877 Weak Pair(2016 ACM/ICPC Asia Regional Dalian Online)
- 对DSP5509A时钟发生器的调试
- master_opencv关于车牌识别工程框架整理
- Graph-slam(三)
- JAVA学习笔记之(读取XML)
- [python] 安装numpy+scipy+matlotlib+scikit-learn及问题解决
- Java设计模式——抽象工厂模式(Abstract Factory Pattern)
- 深度理解链式前向星(转)
- 无限加载瀑布流