这题也是一眼标算.....

先搞一次dfs,把树转换成序列,对每个节点看子树的中位数,也就是看某段区间的中位数,这样就可以主席树求区间第k大值解决。

注意:询问的次数有1000000次,每次去询问会TLE的。注意到询问的种类只有100000种,所以之前询问过的可以0(1)得到,或者直接处理出每一种询问的答案。

还有一个问题:小数取模...用fmod函数。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<vector>
#include<algorithm>
using namespace std; inline bool scan_d(int &num)
{
char in; bool IsN = false;
in = getchar();
if (in == EOF) return false;
while (in != '-' && (in<'' || in>'')) in = getchar();
if (in == '-'){ IsN = true; num = ; }
else num = in - '';
while (in = getchar(), in >= ''&&in <= ''){
num *= , num += in - '';
}
if (IsN) num = -num;
return true;
} #define mod 1000000007
const int maxn = ;
double Ans[maxn];
vector<int>Tree[maxn];
int tmp_n, Q;
int val[maxn];
int L[maxn], R[maxn];
int time; const int MAXN = ;
const int M = MAXN * ;
int n, q, m, tot;
int a[MAXN], t[MAXN];
int T[M], lson[M], rson[M], c[M]; void Init_hash()
{
for (int i = ; i <= n; i++)
t[i] = a[i];
sort(t + , t + + n);
m = unique(t + , t + + n) - t - ;
}
int build(int l, int r)
{
int root = tot++;
c[root] = ;
if (l != r)
{
int mid = (l + r) >> ;
lson[root] = build(l, mid);
rson[root] = build(mid + , r);
}
return root;
}
int HASH(int x)
{
return lower_bound(t + , t + + m, x) - t;
}
int update(int root, int pos, int val)
{
int newroot = tot++, tmp = newroot;
c[newroot] = c[root] + val;
int l = , r = m;
while (l < r)
{
int mid = (l + r) >> ;
if (pos <= 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 + ;
}
c[newroot] = c[root] + val;
}
return tmp;
}
int query(int left_root, int right_root, int k)
{
int l = , r = m;
while (l < r)
{
int mid = (l + r) >> ;
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 + ;
k -= c[lson[left_root]] - c[lson[right_root]];
left_root = rson[left_root];
right_root = rson[right_root];
}
}
return l;
} void dfs(int now)
{
L[now] = ++time;
a[time] = val[now];
for (int i = ; i < Tree[now].size(); i++)
dfs(Tree[now][i]);
R[now] = ++time;
a[time] = val[now];
} int main()
{
int Case; scanf("%d", &Case);
while (Case--)
{
scanf("%d%d", &tmp_n, &Q); for (int i = ; i <= tmp_n; i++)
{
scan_d(val[i]);
Tree[i].clear();
} for (int i = ; i <= tmp_n - ; i++)
{
int u, v;
scan_d(u); scan_d(v);
Tree[u].push_back(v);
} time = ;
dfs();
n = time; tot = ;
Init_hash(); T[n + ] = build(, m); for (int i = n; i; i--)
{
int pos = HASH(a[i]);
T[i] = update(T[i + ], pos, );
} for (int i = ; i <= tmp_n; i++)
{
int l = L[i], r = R[i];
if ((l - r + ) % == )
{
int k = (l + r) / - l + ;
Ans[i] = 1.0*t[query(T[l], T[r + ], k)];
}
else
{
int k1 = (l + r) / - l + ;
int k2 = (l + r) / - l + ;
Ans[i] = 1.0*(t[query(T[l], T[r + ], k1)] + t[query(T[l], T[r + ], k2)]) / 2.0;
}
}
double f = ; for (int i = ; i <= Q; i++)
{
int id; scan_d(id);
f = fmod(f * + Ans[id], mod);
}
printf("%.1lf\n", f);
}
return ;
}

HDU 5678 ztr loves trees的更多相关文章

  1. HDU 5677 ztr loves substring(Manacher+dp+二进制分解)

    题目链接:HDU 5677 ztr loves substring 题意:有n个字符串,任选k个回文子串,问其长度之和能否等于L. 题解:用manacher算法求出所有回文子串的长度,并记录各长度回文 ...

  2. HDU 5675 ztr loves math (数学推导)

    ztr loves math 题目链接: http://acm.hust.edu.cn/vjudge/contest/123316#problem/A Description ztr loves re ...

  3. HDU 5676 ztr loves lucky numbers (模拟)

    ztr loves lucky numbers 题目链接: http://acm.hust.edu.cn/vjudge/contest/121332#problem/I Description ztr ...

  4. HDU 5675 ztr loves math

    ztr loves math Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  5. hdu 5676 ztr loves lucky numbers(dfs+离线)

    Problem Description ztr loves lucky numbers. Everybody knows that positive integers are lucky if the ...

  6. hdu 5675 ztr loves math(数学技巧)

    Problem Description ztr loves research Math.One day,He thought about the "Lower Edition" o ...

  7. hdu 5676 ztr loves lucky numbers 打表+二分

    ztr loves lucky numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/ ...

  8. HDU 5677 ztr loves substring(回文串加多重背包)

    ztr loves substring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  9. hdu 5677 ztr loves substring 多重背包

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission( ...

随机推荐

  1. maven之pom

    记录一下最近的pom的相关设置,plugin的官方地址配置:http://maven.apache.org/plugins/index.html 看了网上说了很多例子,有很多不清楚,看一下官方的,会有 ...

  2. wpf之ListBox横向显示所有ListBoxItem

    Xaml: <Window x:Class="WpfApplication6.MainWindow" xmlns="http://schemas.microsoft ...

  3. C#之控制台输入和输出

    控制台输出 C# 控制台程序一般使用 .NET Framework Console 类提供的输入/输出服务.Console.WriteLine("Hello World!"); 语 ...

  4. codeforces 689B Mike and Shortcuts 最短路

    题目大意:给出n个点,两点间的常规路为双向路,路长为两点之间的差的绝对值,第二行为捷径,捷径为单向路(第i个点到ai点),距离为1.问1到各个点之间的最短距离. 题目思路:SPFA求最短路 #incl ...

  5. POJ3321/Apple tree/(DFS序+线段树)

    题目链接 Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9692 Accepted: 3217 Descr ...

  6. parseint和parsefloat总结number。隐形转换

    parseint:会认识一些字符+.-.空格,其他的就会截止譬如23hudhchauch结果为:23,对于boollen类型不能转换为1或是0. number:是对整体的转换.对true的转换为1. ...

  7. acm课程练习2--1013(同1014)

    题目描述 There is a strange lift.The lift can stop can at every floor as you want, and there is a number ...

  8. Hibernate锁机制

    业务逻辑的实现过程中,往往需要保证数据访问的排他性.因此,我们就需要通过一些机制来保证这些数据在某个操作过程中不会被外界修改,这样的机制,在这里,也就是所谓的“锁”,即给我们选定的目标数据上锁,使其无 ...

  9. JavaScript(四)---- 函数

    函数主要用来封装具体的功能代码. 函数是由这样的方式进行声明的:关键字 function.函数名.一组参数,以及置于括号中的待执行代码. 格式: function 函数名(形参列表){         ...

  10. P2P应用中的NAT穿透问题

    多年前曾经写过一个关于NAT钻洞的实验.现在发现那个做法在我现在的路由器上已经不管用了.经过一番搜索发现时过境迁,世界变化很快,新路由器已经是UPnP了.在这里重新理一下几种方法. 第一种,也是不太靠 ...