hdu 5678 ztr loves trees(求子树第k大 线段树套主席树)
来源:互联网 发布:自动校时软件 编辑:程序博客网 时间:2024/04/29 00:12
ztr loves trees
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.
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,
Sample Input
15 31 2 3 4 51 22 33 44 5123
Sample Output
339.
此题要求子树第k大,那么我们可以用dfs序预处理出来以i为根的子树区间为l[i]~r[i],之后就是用主席树套线段树求区间第k大(模板),但还需要做一些处理,若是偶数,则中位数还有可能有小数,因此用pair解决即可,详细请看代码,欢迎讨论~
#include <cstdio>#include <cstring>#include <algorithm>#include<iostream>using namespace std;typedef long long ll;#define pii pair <ll, int>#define xx first#define yy secondusing namespace std;const int maxn = 110000;const int mod = 1e9 + 7;int T[maxn], num[maxn], san[maxn], ls[maxn * 20], rs[maxn * 20], sum[maxn * 20], l[maxn], r[maxn], a[maxn];pii res[maxn];int tot, rt, dfsxu, cc;int head[maxn];struct edge {int to, next;} e[maxn * 2];void add(int u, int v) {e[cc].to = v; e[cc].next = head[u];head[u] = cc++;}int sz[maxn];void dfs(int u, int fa) //dfs序{sz[u] = 1;l[u] = ++dfsxu;num[dfsxu] = san[dfsxu] = a[u];for (int i = head[u]; i!=-1; i = e[i].next) {int v = e[i].to;dfs(v, u);sz[u] += sz[v];}r[u] = dfsxu;}void Build(int l, int r, int &rt){rt = ++tot;sum[rt] = 0;if (l == r) return;int m = (l + r) >> 1;Build(l, m, ls[rt]);Build(m + 1, r, rs[rt]);}void Update(int last, int p, int l, int r, int &rt){rt = ++tot;ls[rt] = ls[last];rs[rt] = rs[last];sum[rt] = sum[last] + 1;if (l == r) return;int m = (l + r) >> 1;if (p <= m) Update(ls[last], p, l, m, ls[rt]);else Update(rs[last], p, m + 1, r, rs[rt]);}int Query(int ss, int tt, int l, int r, int k){if (l == r) return l;int m = (l + r) >> 1;int cnt = sum[ls[tt]] - sum[ls[ss]];if (k <= cnt)return Query(ls[ss], ls[tt], l, m, k);elsereturn Query(rs[ss], rs[tt], m + 1, r, k - cnt);}void solve(){tot = 0;sort(san + 1, san + dfsxu + 1);int cnt=unique(san + 1, san + dfsxu + 1) - san - 1;Build(1, cnt, T[0]);for (int i = 1; i <= dfsxu; i++) num[i] = lower_bound(san + 1, san + cnt + 1, num[i]) - san;for (int i = 1; i <= dfsxu; i++) Update(T[i - 1], num[i], 1, cnt, T[i]);for (int i = 1; i <= dfsxu; i++) if (sz[i] & 1) res[i] = pii(san[Query(T[l[i] - 1], T[r[i]], 1, cnt, sz[i] / 2 + 1)], 0);else {int tmp = san[Query(T[l[i] - 1], T[r[i]], 1, cnt, sz[i] / 2)] + san[Query(T[l[i] - 1], T[r[i]], 1, cnt, sz[i] / 2 + 1)];res[i] = pii(tmp / 2, tmp & 1);}}void init(){cc = 0; dfsxu = 0; tot = 0;memset(head, -1, sizeof head);}int main(){int T,n, m, u, v, x;;scanf("%d", &T);while (T--){init();scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)scanf("%d", &a[i]);for (int i = 1; i < n; i++) {scanf("%d%d", &u, &v);add(u, v);}dfs(1, 0);solve();pii ans = pii(0, 0);while (m--) {scanf("%d", &x);ans.xx *= 10;if (ans.yy) ans.yy = 0, ans.xx += 5;ans.xx += res[x].xx;ans.yy += res[x].yy;ans.xx %= mod;}cout << ans.xx;if (ans.yy) cout << ".5" << endl;else cout << ".0" << endl;}return 0;}
0 1
- hdu 5678 ztr loves trees(求子树第k大 线段树套主席树)
- hdu 5678 ztr loves trees(dfs序、主席树静态第k大)
- HDU 5678 ztr loves trees
- 区间第k大 可修改主席树,树状数组套线段树。
- hdu 2665 可持久化线段树求区间第K大值(函数式线段树||主席树)
- ZOJ 2112 Dynamic Rankings(线段树套treap求动态第K大)
- ZOJ 2112 Dynamic Rankings 树状数组套主席树 单点修改求动态区间第K大
- hdu 5412 CRB and Queries(线段树套笛卡尔树 - 动态区间第k大)
- HDU 2665 主席树(求区间第k大模板)
- 主席树求静态区间第K大
- 主席树---求第k大的数 poj2104
- 主席树 --- 求区间第k大值
- 动态区间第k小(主席树+线段树套树状数组)
- 学习笔记--函数式线段树(主席树)(动态维护第K极值(树状数组套主席树))
- hdu 5678 ztr loves trees (给一颗有根树,树上的每一个节点有一个权值,每次询问某个子树中所有权值的中位数)
- zoj 2112 树状数组 套主席树 动态求区间 第k个数
- bzoj3110[Zjoi2013]K大数查询 主席树套线段树
- hdu 2665 区间第K大 主席树入门
- Palindrome-detection quiz
- 2016 UESTC Training for Data Structures H - 郭大侠与英雄学院 CDOJ 1338 并查集
- 设计模式:观察者模式(Observer)
- XML
- 深度学习-浅谈CNNs
- hdu 5678 ztr loves trees(求子树第k大 线段树套主席树)
- tractor quiz
- 问题修正
- @RequestMapping
- 巧用Singleton(单例)
- [转] ARM 和 X86 的区别
- Hive 和 Hadoop 关系
- 2016 UESTC Training for Data Structures I - 郭大侠与线上游戏 CDOJ 1339 pb_ds黑科技
- Android开发:Handler异步通信机制全面解析(包含Looper、Message Queue