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

先搞一次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. CLR 无法从 COM

    上下文 0x50ece80 转换为 COM 上下文 0x50ecf38,这种状态已持续 60 秒.拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个 ...

  2. listctrl中的cell如何支持被复制

    为了方便测试data pipeline, 使用wxpython开发了一个小工具,用来显示csv文档中的特定列,及数据库中的指定值. 显示数据的contrl选择了listctrl.但这里有个问题,显示的 ...

  3. javascript IP验证

    //IP验证function isIP(strIP){try{if(strIP.length<7){return false;}var re=/^(\d+)\.(\d+)\.(\d+)\.(\d ...

  4. UVA 1193 区间相关(greedy)

    input n d 1<=n<=1000 n行坐标xi,yi output 位于x轴扫描器的扫描距离为d,至少要多少个扫描器才能扫描到所有坐标 如果无法扫描完输出-1,否则输出扫描器个数 ...

  5. UIViewContentMode 图文解说

    在iOS应用开发中我们常常要对视图的contentMode属性进行设置,尤其在使用UIImageView视图时设置这个属性的概率很高.我们知道contentMode的类型是UIViewContentM ...

  6. CodeForces 567B Berland National Library

    Description Berland National Library has recently been built in the capital of Berland. In addition, ...

  7. Datatable.select() 方法的使用

    文章为转载 ,原文地址 DataTable是我们在进行开发时经常用到的一个类,并且经常需要对DataTable中的数据进行筛选等操作,下面就介绍一下Datatable中经常用到的一个方法--Selec ...

  8. ZEN_CART_如何添加自定义页面

    按照下面的路径,添加自己的文件,就OK了 以about us页面为例, 默认模板 \includes\templates\template_default\templates\tpl_about_us ...

  9. CentOS 6.5 安装Suricata(with PF_RING & CUDA)

    0.基础包 确保已安装 yum install mpfr cpp ppl cloog-ppl gcc kernel-devel pcre-devel libpcap-devel yum-plugin- ...

  10. Service Activity三种交互方式

    Service Activity三种交互方式 2012-09-09 22:52 4013人阅读 评论(2) 收藏 举报 serviceandroidimportclassthreadjava     ...