hdu 4605(树状数组+离散化)
2015-08-17 23:50
375 查看
题意:一棵树上每个节点都有权值,一个球从根节点往下走,每个球都有一个权值x,如果x大于当前节点的权值w[i],有1/8的概率走左边孩子节点,有7/8的概率走右边孩子节点,如果x等于当前节点的权值w[i]或者当前节点是叶子节点,则球停止下落,如果x小于当前节点的权值,各1/2的概率走左右孩子节点。现在给出一个球的权值和它的目的节点,问能走到目的节点的概率,概率是7^x/2^y,输出x y。
题解:因为是一棵树,从根节点走到目的节点只有确定的一条路径可走,那么计算概率只需要统计,这条路径向左孩子节点走的节点的权值比x大的有ld个,比x小的有lx个,向右孩子节点走的节点的权值比x大的有rd个,比x小的有rx个,明显x = rd,y = (lx + rx) + (ld + rd) * 3。为了统计要走的路径中节点权值比x大的个数,可以树状数组,因为权值到1e9,要离散化处理。
题解:因为是一棵树,从根节点走到目的节点只有确定的一条路径可走,那么计算概率只需要统计,这条路径向左孩子节点走的节点的权值比x大的有ld个,比x小的有lx个,向右孩子节点走的节点的权值比x大的有rd个,比x小的有rx个,明显x = rd,y = (lx + rx) + (ld + rd) * 3。为了统计要走的路径中节点权值比x大的个数,可以树状数组,因为权值到1e9,要离散化处理。
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int N = 100005; int n, m, w , a[N << 2], cnt, res [2], C[2][N << 2]; vector<pair<int, int> > query ; vector<int> g ; int lowbit(int x) { return x & (-x); } int Sum(int x, int y) { int ret = 0; while (x > 0) { ret += C[y][x]; x -= lowbit(x); } return ret; } void Add(int x, int d, int y) { while (x <= cnt) { C[y][x] += d; x += lowbit(x); } } void dfs(int u) { int sz = query[u].size(); for (int i = 0; i < sz; i++) { int id = query[u][i].first; int x = query[u][i].second; int pos = lower_bound(a, a + cnt, x) - a + 1; int ld = Sum(pos - 1, 0); int rd = Sum(pos - 1, 1); int la = Sum(cnt, 0); int ra = Sum(cnt, 1); int lx = la - Sum(pos, 0); int rx = ra - Sum(pos, 1); if (ld + lx + rd + rx != la + ra) { res[id][0] = -1; continue; } res[id][0] = rd; res[id][1] = lx + rx + (ld + rd) * 3; } sz = g[u].size(); for (int i = 0; i < sz; i++) { int v = g[u][i]; int x = w[u]; int pos = lower_bound(a, a + cnt, x) - a + 1; Add(pos, 1, i); dfs(v); Add(pos, -1, i); } } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d", &n); cnt = 0; for (int i = 1; i <= n; i++) { scanf("%d", &w[i]); a[cnt++] = w[i]; g[i].clear(); query[i].clear(); } scanf("%d", &m); int u, v1, v2, q, v, x; for (int i = 1; i <= m; i++) { scanf("%d%d%d", &u, &v1, &v2); g[u].push_back(v1); g[u].push_back(v2); } scanf("%d", &q); for (int i = 0; i < q; i++) { scanf("%d%d", &v, &x); query[v].push_back(make_pair(i, x)); a[cnt++] = x; } sort(a, a + cnt); cnt = unique(a, a + cnt) - a; dfs(1); for (int i = 0; i < q; i++) if (res[i][0] != -1) printf("%d %d\n", res[i][0], res[i][1]); else printf("0\n"); } return 0; }
相关文章推荐
- [图论训练]BZOJ 3245: 最快路线【最短路】
- POJ 1061 青蛙的约会(拓展欧几里得)
- 就快结束了
- AES 对称加密算法 加密\解密实例
- jvm(1)----java内存区域与内存溢出异常
- Java中Class.forName和ClassLoader.loadClass的区别
- vagrant 学习
- Scala深入浅出实战经典《第86讲:Scala中For表达式的生成器、定义和过滤器》笔记
- uva 11536 Smallest Sub-Array
- Solr使用入门指南
- Linux 包安装
- Scala深入浅出实战经典《第88讲:Scala中使用For表达式实现map、flatMap、filter》笔记
- 匿名类对象及可变参数
- RT-Thread finsh源码分析: finsh_heap.h
- POJ 2828 Buy Tickets(线段树)
- myeclipse-eclipse_web工程互导
- 纱布の莫比乌斯反演的一些理解。
- 凤姐都在理财了,你在干什么?
- Scala深入浅出实战经典《第87讲:Scala中使用For表达式做查询》笔记
- Java基础---判断结构示例