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
原创粉丝点击