zoukankan      html  css  js  c++  java
  • HDU5678 ztr loves trees (可持久化线段树)

    给你一棵树,每次询问节点子树的中值。

    在DFS序上建线段树,用fmod给double取模。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+100;
    const int M=maxn*40;
    const int mod=1e9+7;
    int n,m,q;
    int a[maxn];
    int t[maxn];
    int T[maxn];
    int lson[M],rson[M],c[M],tot;
    int build (int l,int r) {
        int root=tot++;
        c[root]=0;
        if (l!=r) {
            int mid=(l+r)>>1;
            lson[root]=build(l,mid);
            rson[root]=build(mid+1,r);
        }
        return root;
    }
    int up (int root,int p,int v) {
        int newRoot=tot++;
        int tmp=newRoot;
        int l=1,r=m;
        c[newRoot]=c[root]+v;
        while (l<r) {
            int mid=(l+r)>>1;
            if (p<=mid) {
                lson[newRoot]=tot++;
                rson[newRoot]=rson[root];
                newRoot=lson[newRoot];
                root=lson[root];
                r=mid;
            }
            else {
                rson[newRoot]=tot++;
                lson[newRoot]=lson[root];
                newRoot=rson[newRoot];
                root=rson[root];
                l=mid+1;
            }
            c[newRoot]=c[root]+v;
        }
        return tmp;
    }
    
    int query (int left_root,int right_root,int k) {
        int l=1,r=m;
        while (l<r) {
            int mid=(l+r)>>1;
            if (c[lson[left_root]]-c[lson[right_root]]>=k) {
                r=mid;
                left_root=lson[left_root];
                right_root=lson[right_root];
            }
            else {
                l=mid+1;
                k-=c[lson[left_root]]-c[lson[right_root]];
                left_root=rson[left_root];
                right_root=rson[right_root];
            } 
        }
        return l;
    }
    int w[maxn];
    int id[maxn];
    int tol;
    int size[maxn];
    vector<int> g[maxn];
    void dfs (int u,int pre) {
        id[u]=++tol;
        w[tol]=a[u];
        size[u]=1;
        for (int v:g[u]) {
            if (v==pre) continue;
            dfs(v,u); 
            size[u]+=size[v];
        }
    }
    double ans[maxn];
    
    int main () {
        int _;
        scanf("%d",&_);
        while (_--) {
            scanf("%d%d",&n,&q);
            tot=tol=0;
            for (int i=1;i<=n;i++) scanf("%d",a+i),t[i]=a[i],g[i].clear();
            for (int i=1;i<n;i++) {
                int x,y;
                scanf("%d%d",&x,&y);
                g[x].push_back(y);
                g[y].push_back(x);
            }
            sort(t+1,t+n+1);
            m=unique(t+1,t+n+1)-t-1;
            for (int i=1;i<=n;i++) a[i]=upper_bound(t+1,t+m+1,a[i])-t-1;
            dfs(1,0);
            T[n+1]=build(1,m);
            for (int i=n;i;i--) T[i]=up(T[i+1],w[i],1);
            double sum=0;
            for (int i=1;i<=n;i++) {
                if (size[i]%2) {
                    ans[i]=t[query(T[id[i]],T[id[i]+size[i]],size[i]/2+size[i]%2)];
                }
                else {
                    ans[i]=(t[query(T[id[i]],T[id[i]+size[i]],size[i]/2)]+t[query(T[id[i]],T[id[i]+size[i]],size[i]/2+1)])*1.0/2;
                }
            }
            for (int i=1;i<=q;i++) {
                int x;
                scanf("%d",&x);
                sum=fmod(sum*10+ans[x],(double)mod);
            }
            printf("%.1f
    ",(double)sum);
        }
    }
  • 相关阅读:
    【Python大系】Python快速教程
    【Linux大系】Linux的概念与体系
    【Java大系】Java快速教程
    【夯实PHP系列】PHP正则表达式
    【PHP夯实基础系列】PHP日期,文件系统等知识点
    【夯实PHP系列】购物车代码说明PHP的匿名函数
    2016.09.21 公司裁员想到的
    使用android-junit-report.jar导出单元测试报告
    APK无源码使用Robotium简单总结
    Android环境安装简单总结
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14017022.html
Copyright © 2011-2022 走看看