ztr loves trees
Time Limit: 6000/2500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 296 Accepted Submission(s): 46
Problem Description
Super Deity ztr likes trees from childhood,CCTV-children:"The apple on the apple tree.You and I under the apple tree.Play games in front of the apple tree.So many happiness".
One day,qzh visit ztr to ask some questions.To give a tree with a root,each vertex has a value.Each time query the median of a subtree.
ztr said:this is a water problem,do you do it?But qzh show cannot help but want you who is also a Super Deity to help him.Could you help him?
One day,qzh visit ztr to ask some questions.To give a tree with a root,each vertex has a value.Each time query the median of a subtree.
ztr said:this is a water problem,do you do it?But qzh show cannot help but want you who is also a Super Deity to help him.Could you help him?
Input
There are T test cases. The first line of input contains an positive integer T indicating the number of test cases.
For each test case:
Each line contains two positive integer n,m.indicating the number of vetrex and the number of query times.
The next line contains n numbers, the ith number indicating the value of vertex i.
The next n-1 lines,each line contains two numbers u and v,indicating there is a edge form u to v.
The next m lines, each line contains a numbers x.indicating query the median of subtree x.
1<=T<=3,1<=n<=105,1<=m<=106,1<=u<=v<=n,1<=val<=109.
The vetrex 1 is the root of the tree.Guarantee input a tree with a root.
For each test case:
Each line contains two positive integer n,m.indicating the number of vetrex and the number of query times.
The next line contains n numbers, the ith number indicating the value of vertex i.
The next n-1 lines,each line contains two numbers u and v,indicating there is a edge form u to v.
The next m lines, each line contains a numbers x.indicating query the median of subtree x.
1<=T<=3,1<=n<=105,1<=m<=106,1<=u<=v<=n,1<=val<=109.
The vetrex 1 is the root of the tree.Guarantee input a tree with a root.
Output
For each test case:print a line.To avoid huge output,you should hash each answer first,then print it.
The method to hash:a[i] indicates the ith query result, ans=∑a[i]∗10m−imod1,000,000,007 Round to the nearest tenth
The method to hash:a[i] indicates the ith query result, ans=∑a[i]∗10m−imod1,000,000,007 Round to the nearest tenth
Sample Input
1 5 3 1 2 3 4 5 1 2 2 3 3 4 4 5 1 2 3
Sample Output
339.0
给一颗有根树,树上的每一个节点有一个权值,每次询问某个子树中所有权值的中位数
思路:
这道题就是在一个子树上询问第k大,于是我们用dfs序将树上询问第k大转化为区间询问第k大,套用主席树即可.
#include<cstdio>
#include<algorithm>
#include<time.h>
#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
#include<math.h>
#include<vector>
#include<algorithm>
#include<stdio.h>
#include<map>
using namespace std;
#define maxn 100005
const int MOD=1000000007;
int val[maxn],L[maxn],R[maxn],tot,a[maxn],t[maxn],vis[maxn];
vector<int>G[maxn];
int root[maxn],sz;
double ans[maxn];
struct node{
int l,r,w;
}T[maxn*30];
void dfs(int u){
vis[u]=1;
L[u]=++tot;
t[tot]=val[u],a[tot]=val[u];
for(int i=0;i<G[u].size();i++){
int v=G[u][i];
if(vis[v]==1)
continue;
dfs(v);
}
R[u]=tot;
}
void update(int &i,int l,int r,int num){
T[++sz]=T[i],i=sz;
T[i].w++;
if(l==r)
return ;
int mid=(l+r)>>1;
if(num<=mid)
update(T[i].l,l,mid,num);
else
update(T[i].r,mid+1,r,num);
}
int query(int x,int y,int l,int r,int k){
if(l==r)
return l;
int mid=(l+r)>>1;
int num=T[T[y].l].w-T[T[x].l].w;
if(num>=k)
return query(T[x].l,T[y].l,l,mid,k);
else
return query(T[x].r,T[y].r,mid+1,r,k-num);
}
int main(){
int _,n,m,u,v,q;
scanf("%d",&_);
while(_--){
scanf("%d%d",&n,&q);
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
scanf("%d",&val[i]);
G[i].clear();
}
for(int i=1;i<n;i++){
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
tot=0;
dfs(1);
sort(t+1,t+n+1);
int m=unique(t+1,t+n+1)-t-1;
root[0]=0,sz=0;
for(int i=1;i<=n;i++){ //有序
root[i]=root[i-1];
int num=lower_bound(t+1,t+m+1,a[i])-t;
update(root[i],1,n,num);
}
for(int i=1;i<=n;i++){
if((R[i]-L[i])%2==1){
int num1=query(root[L[i]-1],root[R[i]],1,n,(R[i]-L[i]+1)/2);
int num2=query(root[L[i]-1],root[R[i]],1,n,(R[i]-L[i]+1)/2+1);
ans[i]=1.0*(t[num1]+t[num2])/2;
}
else
ans[i]=t[query(root[L[i]-1],root[R[i]],1,n,(R[i]-L[i])/2+1)];
}
double ANS=0;
for(int i=1;i<=q;i++){
scanf("%d",&u);
ANS=fmod(ans[u]+ANS*10,1.0*MOD);
}
printf("%.1f\n",ANS);
}
return 0;
}