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;
    }
    
  • 相关阅读:
    嵌入式Linux的启动过程
    【转载】vim 中文帮助手册的安装
    面向对象之编写驱动程序--中断(linux系统、s3c6410开发板)
    【转】DBCC IND / DBCC PAGE
    【转】索引查询 sys.dm_db_index_physical_stats
    【tag】Enum.HasFlag 方法
    【tag】Tuple 类 使用介绍
    【fixed point】柯里化(currying) C#实现
    SqlDataAdapter 批量更新 DataTable
    sqlCacheDependency 使用
  • 原文地址:https://www.cnblogs.com/ftae/p/7747647.html
Copyright © 2011-2022 走看看