您的位置:首页 > 其它

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,要离散化处理。

#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: