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

先搞一次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. linux daemon

    参考 鸟哥的私房菜 http://linux.vbird.org/linux_basic/0560daemons.php

  2. oracle的row_number()和rownum

    row_number() 函数和rownum的介绍: 1.row_number() 方法的格式: row_number()over([partition by col1] order by col2) ...

  3. AI 人工智能 探索 (六)

    这次我为 角色 attribute 添加了 多个属性 其中 att 是 好人 坏人 等属性, 显然 数字不同 就要打起来. grade 是智商属性 ,今天先做了 3的智商.也就是小兵智商.碰到就打 逃 ...

  4. ACM暑期训练总结

    ACM暑期集训总结报告 不知不觉,ACM暑期集训已经过去了一个月了(其实我还差几天才够一个月,因为最后几天要回家办助学贷款,所以没坚持到最后,当了个逃兵.....[汗])也到了结束的时候.在这一个月中 ...

  5. 关于this指针理解

    1. this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果.this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将 ...

  6. c++ data语意学

     Data Member的绑定 extern float x; class Point3d { public: point3d(); //问题:被传回和被设定的x是哪一个x呢? float X() c ...

  7. Telepro工具注册码

    Teleport Pro v1.54 注册码 Teleport Pro v1.54姓名(Name):3ddown.com序列号(Serial):161594593

  8. hdu_5738_Eureka(脑洞)

    题目链接:hdu_5738_Eureka 题意: 这题感觉说不清楚,坑点有点坑,一不小心就会推出错误的公式,然后最重要的是你还不知道你推错了 题解: 这里贴一个官方的题解 Eureka xjb推导一下 ...

  9. jq中的ajax

    jq对ajax进行了封装,在jq中$.ajax()方法是最底层的方法,第二层是load() , get() , post()方法,第三层是$.getScript()和$.getJSON().基本第二种 ...

  10. cisco 密码重置

    密码重置 分类: 转贴技术资料 2007-12-28 16:38 http://www.cisco.com/en/US/products/hw/routers/ps259/products_passw ...