zoukankan      html  css  js  c++  java
  • hdu4605

    hdu4605

    题意

    给出一棵带权值的树,多个查询 (v, X),某个重量为 (X) 的小球从根结点出发,根据 (X) 与当前结点权值的大小关系决定走左右子结点的概率,问到达 (v) 结点的概率。

    分析

    先离散化,再树状数组维护路径上结点的值,查询离线处理。

    code

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int MAXN = 1e5 + 5;
    int l[MAXN], r[MAXN], c[MAXN];
    vector<int> v1[MAXN], v2[MAXN];
    int x[MAXN], y[MAXN], d[MAXN << 1];
    int f[2][MAXN];
    void update(int p, int k, int z) {
        while(k < MAXN) {
            f[p][k] += z;
            k += k & -k;
        }
    }
    int query(int p, int k) {
        int a = 0;
        while(k) {
            a += f[p][k];
            k -= k & -k;
        }
        return a;
    }
    void dfs(int u) {
        for(int i = 0; i < v1[u].size(); i++) {
            int a = v2[u][i], b = v1[u][i];
            if((u != 1 && a == c[1]) || query(0, a) - query(0, a - 1) > 0 || query(1, a) - query(1, a - 1) > 0) x[b] = -1;
            else {
                int cnt01 = query(0, a - 1), cnt00 = query(0, MAXN - 1) - query(0, a);
                int cnt11 = query(1, a - 1), cnt10 = query(1, MAXN - 1) - query(1, a);
                y[b] = cnt00 + cnt10 + 3 * (cnt01 + cnt11);
                x[b] = cnt11;
            }
        }
        if(l[u]) {
            update(0, c[u], 1);
            dfs(l[u]);
            update(0, c[u], -1);
            update(1, c[u], 1);
            dfs(r[u]);
            update(1, c[u], -1);
        }
    }
    int main() {
        int T;
        scanf("%d", &T);
        while(T--) {
            memset(l, 0, sizeof l);
            memset(f, 0, sizeof f);
            int n, m;
            scanf("%d", &n);
            for(int i = 1; i <= n; i++) {
                v1[i].clear();
                v2[i].clear();
                scanf("%d", &c[i]);
                d[i] = c[i];
            }
            scanf("%d", &m);
            while(m--) {
                int u, a, b;
                scanf("%d%d%d", &u, &a, &b);
                l[u] = a;
                r[u] = b;
            }
            int q;
            scanf("%d", &q);
            int cnt = n;
            for(int i = 0; i < q; i++) {
                int a, b;
                scanf("%d%d", &a, &b);
                v1[a].push_back(i);
                v2[a].push_back(b);
                d[++cnt] = b;
            }
            sort(d + 1, d + 1 + cnt);
            int nn = unique(d + 1, d + 1 + cnt) - d - 1;
            for(int i = 1; i <= n; i++) {
                c[i] = lower_bound(d + 1, d + 1 + nn, c[i]) - d;
                for(int j = 0; j < v2[i].size(); j++) v2[i][j] = lower_bound(d + 1, d + 1 + nn, v2[i][j]) - d;
            }
            dfs(1);
            for(int i = 0; i < q; i++) {
                if(x[i] == -1) printf("0
    ");
                else printf("%d %d
    ", x[i], y[i]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    1212. 地宫取宝
    895. 最长上升子序列
    高層タワー [MISSION LEVEL: B]
    分组背包
    多重背包
    1015. 摘花生
    1211. 蚂蚁感冒
    1205. 买不到的数目
    SQL基础教程(第2版)第4章 数据更新:4-2 数据的删除(DELETE)
    SQL基础教程(第2版)第4章 数据更新:4-1 数据的插入(INSERT)
  • 原文地址:https://www.cnblogs.com/ftae/p/7747647.html
Copyright © 2011-2022 走看看