ztr loves trees
Time Limit: 6000/2500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 611 Accepted Submission(s): 133
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
Source
Recommend
wange2014
题意:给一颗有根树,树上的每一个节点有一个权值,每次询问某个子树中所有权值的中位数
解题思路:dfs序+主席树即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <map>
#include <cmath>
#include <set>
#include <stack>
#include <queue>
#include <vector>
#include <bitset>
#include <functional>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
int n, q, cnt, tot,res,x,y;
int s[100005], nt[200005], e[200005];
int a[100005],xx[100005];
int rt[100005], L[100005 * 40], R[100005 * 40], sum[100005 * 40];
double ans[100005];
void add(int pre, int &now, int l, int r, int p)
{
sum[now=++tot] = sum[pre] + 1;
if (l == r) { L[now] = R[now] = 0; return; }
int mid = (l + r) >> 1;
L[now] = L[pre], R[now] = R[pre];
if (mid >= p) add(L[pre], L[now], l, mid, p);
else add(R[pre], R[now], mid + 1, r, p);
}
int query(int pre, int now, int l, int r, int p)
{
if (l == r) return l;
int mid = (l + r) >> 1;
if (sum[L[now]] - sum[L[pre]] >= p) return query(L[pre], L[now], l, mid, p);
return query(R[pre], R[now], mid + 1, r, p - sum[L[now]] + sum[L[pre]]);
}
double solve(int k, int kk)
{
if ((kk - k) & 1) return query(rt[k], rt[kk], 0, 1e9, (kk - k + 1) / 2);
return (query(rt[k], rt[kk], 0, 1e9, (kk - k) / 2) + query(rt[k], rt[kk], 0, 1e9, (kk - k + 2) / 2)) / 2.0;
}
void dfs(int k)
{
xx[k] = ++res;
add(rt[res - 1], rt[res], 0,1e9,a[k]);
for (int i = s[k]; ~i; i = nt[i]) dfs(e[i]);
ans[k] = solve(xx[k] - 1, res);
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &q);
rt[0] = L[0] = R[0] = sum[0] = xx[0] = cnt = res = tot = 0;
memset(s, -1, sizeof s);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i < n; i++)
{
scanf("%d%d", &x, &y);
nt[cnt] = s[x], s[x] = cnt, e[cnt++] = y;
}
dfs(1);
double ans1 = 0;
while (q--)
{
scanf("%d", &x);
ans1 = fmod(ans1 * 10 + ans[x],1000000007);
}
printf("%.1lf\n", ans1);
}
return 0;
}