HDU 5678 ztr loves trees
这题也是一眼标算.....
先搞一次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的更多相关文章
- HDU 5677 ztr loves substring(Manacher+dp+二进制分解)
题目链接:HDU 5677 ztr loves substring 题意:有n个字符串,任选k个回文子串,问其长度之和能否等于L. 题解:用manacher算法求出所有回文子串的长度,并记录各长度回文 ...
- HDU 5675 ztr loves math (数学推导)
ztr loves math 题目链接: http://acm.hust.edu.cn/vjudge/contest/123316#problem/A Description ztr loves re ...
- HDU 5676 ztr loves lucky numbers (模拟)
ztr loves lucky numbers 题目链接: http://acm.hust.edu.cn/vjudge/contest/121332#problem/I Description ztr ...
- HDU 5675 ztr loves math
ztr loves math Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- hdu 5676 ztr loves lucky numbers(dfs+离线)
Problem Description ztr loves lucky numbers. Everybody knows that positive integers are lucky if the ...
- hdu 5675 ztr loves math(数学技巧)
Problem Description ztr loves research Math.One day,He thought about the "Lower Edition" o ...
- hdu 5676 ztr loves lucky numbers 打表+二分
ztr loves lucky numbers Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/ ...
- HDU 5677 ztr loves substring(回文串加多重背包)
ztr loves substring Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- hdu 5677 ztr loves substring 多重背包
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission( ...
随机推荐
- iptables基础知识
iptables防火墙可以用于创建过滤(filter)与NAT规则.所有Linux发行版都能使用iptables,因此理解如何配置 iptables将会帮助你更有效地管理Linux防火墙.如果你是第一 ...
- git 更新分支
git branch 本地分支 git branch test 创建分支 git pull origin fastboot 更新到最新版本 git branch -a 查看所有的分支,包括本地的和 ...
- NSNumber(把数字存进数组字典等的问题)
官方文档地址https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSNum ...
- libevent linux安装
wget http://monkey.org/~provos/libevent-1.4.13-stable.tar.gzwget http://downloads.sourceforge.net/le ...
- IIS express 7.5 设置默认文档
在C:\Users\[电脑用户名]\Documents\IISExpress\config 下面有个applicationhost.config文件,打开文件找到<system.webServe ...
- webwork <ww:if> 标签的使用
如果在前台(JSP)取出后台的对象的属性,这个属性在后台是属于String 类型的,但若这个属性的值为数字,取出在前台就会默认为整形的值,所以在<ww:if> 判断里面不能加引号:< ...
- java中的类修饰符、成员变量修饰符、方法修饰符
类修饰符: public(访问控制符),将一个类声明为公共类,他可以被任何对象访问,一个程序的主类必须是公共类. abstract,将一个类声明为抽象类,没有实现的方法,需要子类提供方法实现. fi ...
- java方法:flush()
flush本意是冲刷,这个方法大概取自它引申义冲马桶的意思,马桶有个池子,你往里面扔东西,会暂时保存在池子里,只有你放水冲下去,东西才会进入下水道. 同理很多流都有一个这样的池子,专业术语叫缓冲区,当 ...
- Java NIO Related
A file's status is 3-valued: The file is verified to exist; The file is verified to not exist; The f ...
- bos项目经验心得(1)
---恢复内容开始--- 一.搭建数据库环境: 1.在cmd窗口登录mysql数据库: mysql -uroot -proot (mysql登录数据库的形式就是 mysql-u用户名 -p密码) ...