给你一棵树,每次询问节点子树的中值。
在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\n",(double)sum); } }
HDU5678 ztr loves trees (可持久化线段树)
原文:https://www.cnblogs.com/zhanglichen/p/14017022.html