hdu 4605(树状数组+离散化)
来源:互联网 发布:不用网络调频收音机 编辑:程序博客网 时间:2024/05/27 10:42
题意:一棵树上每个节点都有权值,一个球从根节点往下走,每个球都有一个权值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,要离散化处理。
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int N = 100005;int n, m, w[N], a[N << 2], cnt, res[N][2], C[2][N << 2];vector<pair<int, int> > query[N];vector<int> g[N];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;}
0 0
- hdu 4605(树状数组+离散化)
- hdu-4605 Magic Ball Game[离散化+回溯+树状数组]
- HDU-4358-树状数组+离散化
- hdu 3874 树状数组+离散化
- HDU 5101 Select --离散化+树状数组
- HDU 3743 (树状数组,离散化)
- HDU 5654 (树状数组 离散化)
- HDU 5372 (树状数组 离散化)
- HDU 5714 (离散化 树状数组)
- hdu 5372 离散化加树状数组
- hdu 5792 离散化+树状数组
- 树状数组+离散化(hdu 5862)
- hdu 5877 dfs+离散化+树状数组
- HDU 5714 树状数组 + 离散化
- Hdu 4325 Flowers 树状数组+离散化
- hdu 5877 树状数组 +离散化 +树
- hdu 5877(树状数组+离散化)
- hdu 5862(离散化+树状数组)
- vagrant 学习
- jvm(1)----java内存区域与内存溢出异常
- AES 对称加密算法 加密\解密实例
- hdu 1166 敌兵布阵
- Java中Class.forName和ClassLoader.loadClass的区别
- hdu 4605(树状数组+离散化)
- 两种方法实现:输入一个链表,从尾到头打印链表每个节点的值
- hello world!
- css 之殇
- CSU 1542 Flipping Parentheses(线段树)
- nslookup工具
- Mac OS安装使用docker
- nginx环境配置
- JavaScript权威指南_156_第16章_脚本化CSS_16.6-脚本化样式表