SP10628 COT - Count on a tree 主席树
Code:
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<string>
- #include<iostream>
- using namespace std;
- void SetIO(string a){
- string in = a + ".in";
- freopen(in.c_str(),"r",stdin);
- }
- void debug(){
- cout << 233 << endl;
- }
- const int maxn = 100000 + 5;
- int n, m;
- int val[maxn];
- int Sorted[maxn];
- inline void Disperse(){
- sort(Sorted + 1, Sorted + 1 + n);
- for(int i = 1;i <= n; ++i)
- val[i] = lower_bound(Sorted + 1, Sorted + 1 + n, val[i]) - Sorted;
- }
- int head[maxn << 1], to[maxn << 1], nex[maxn << 1], edges;
- inline void add_edge(int u, int v){
- nex[++edges] = head[u];
- head[u] = edges;
- to[edges] = v;
- }
- inline void Read(){
- scanf("%d%d",&n, &m);
- for(int i = 1;i <= n; ++i){
- scanf("%d",&val[i]), Sorted[i] = val[i];
- }
- for(int i = 1;i < n; ++i){
- int a, b;
- scanf("%d%d",&a,&b);
- add_edge(a,b);
- add_edge(b,a);
- }
- }
- const int Tree_const = 50;
- int root[maxn];
- struct Chair_Tree{
- int cnt_node;
- int sumv[maxn * Tree_const], lson[maxn * Tree_const], rson[maxn * Tree_const];
- void build(int l, int r, int &o){
- if(l > r) return ;
- o = ++ cnt_node;
- if(l == r) return ;
- int mid = (l + r) >> 1;
- build(l, mid, lson[o]);
- build(mid + 1, r, rson[o]);
- }
- int insert(int l, int r, int o, int pos){
- int oo = ++cnt_node;
- lson[oo] = lson[o];
- rson[oo] = rson[o];
- sumv[oo] = sumv[o] + 1;
- if(l == r) return oo;
- int mid = (l + r) >> 1;
- if(pos <= mid) lson[oo] = insert(l, mid, lson[o], pos);
- else rson[oo] = insert(mid + 1, r, rson[o], pos);
- return oo;
- }
- int query(int l, int r, int u, int v, int lca, int lca_fa, int k){
- if(l == r) return l;
- int lsum = sumv[lson[u]] + sumv[lson[v]] - sumv[lson[lca]] - sumv[lson[lca_fa]];
- int mid = (l + r) >> 1;
- if(k <= lsum) return query(l, mid, lson[u], lson[v], lson[lca], lson[lca_fa], k);
- else return query(mid + 1, r, rson[u], rson[v], rson[lca], rson[lca_fa], k - lsum);
- }
- }Tree;
- const int logn = 20;
- int f[23][maxn];
- int dep[maxn];
- void dfs(int u, int fa, int depth){
- root[u] = Tree.insert(1, n, root[fa], val[u]);
- dep[u] = depth;
- f[0][u] = fa;
- for(int v = head[u]; v ; v = nex[v]){
- if(to[v] == fa) continue;
- dfs(to[v], u, depth + 1);
- }
- }
- inline void get_ancester(){
- for(int i = 1;i <= logn; ++i){
- for(int j = 1;j <= n; ++j)
- f[i][j] = f[i - 1][f[i - 1][j]];
- }
- }
- inline int get_lca(int a, int b){
- if(dep[a] > dep[b]) swap(a,b);
- if(dep[a] != dep[b]){
- for(int i = logn;i >= 0;--i){
- if(dep[f[i][b]] >= dep[a]) b = f[i][b];
- }
- }
- if(a == b) return a;
- for(int i = logn;i>=0;--i)
- if(f[i][a] != f[i][b]) a = f[i][a], b = f[i][b];
- return f[0][a];
- }
- inline void Build(){
- Tree.build(1, n, root[0]);
- dfs(1, 0, 1);
- get_ancester();
- }
- inline void Init(){
- Read();
- Disperse();
- Build();
- }
- inline void Work(){
- int lastans = 0;
- while(m--){
- int u, v, k;
- scanf("%d%d%d",&u, &v, &k);
- // u ^= lastans;
- int lca = get_lca(u, v);
- lastans = Tree.query(1, n, root[u], root[v], root[lca], root[f[0][lca]], k);
- lastans = Sorted[lastans];
- printf("%d\n", lastans);
- }
- }
- int main(){
- SetIO("input");
- Init();
- Work();
- return 0;
- }
SP10628 COT - Count on a tree 主席树的更多相关文章
- spoj cot: Count on a tree 主席树
10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...
- spoj COT - Count on a tree(主席树 +lca,树上第K大)
您将获得一个包含N个节点的树.树节点的编号从1到Ñ.每个节点都有一个整数权重. 我们会要求您执行以下操作: uvk:询问从节点u到节点v的路径上的第k个最小权重 输入 在第一行中有两个整数Ñ和中号.( ...
- SPOJ Count on a tree(主席树+LCA)
一.题目 COT - Count on a tree You are given a tree with N nodes. The tree nodes are numbered from 1 to ...
- 【BZOJ-2588】Count on a tree 主席树 + 倍增
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 3749 Solved: 873[ ...
- Bzoj 2588: Spoj 10628. Count on a tree 主席树,离散化,可持久,倍增LCA
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2588 2588: Spoj 10628. Count on a tree Time Limit ...
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- 洛谷P2633/bzoj2588 Count on a tree (主席树)
洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...
- 洛谷P2633 Count on a tree(主席树上树)
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...
- 洛谷 P2633 Count on a tree 主席树
在一棵树上,我们要求点 $(u,v)$ 之间路径的第$k$大数. 对于点 $i$ ,建立 $i$ 到根节点的一棵前缀主席树. 简单容斥后不难得出结果为$sumv[u]+sumv[v]−sumv[l ...
随机推荐
- 脑图工具MindNode"附属节点"是什么意思 图解
新手会发现在主节点上无论是按Tab子节点还是按Enter附属节点,都是向右延伸,感觉像没区别? 其实不然,从第二个节点开始,你再按 Tab 或者 Enter 就知道区别了. 废话少说,直接上图. 我觉 ...
- 使用 Shiro 设计基于用户、角色、权限的通用权限管理系统
一.前言 在大型的信息管理系统中,经常涉及到权限管理系统 下面来个 demo,很多复杂的系统的设计都来自它 代码已经放到github上了,地址:https://github.com/larger5/s ...
- 边框的使用,border-radius,box-shadow,border-image
<html> <head> <meta charset="UTF-8"> <title></ ...
- 一些html5
---匿名函数(funcation(){}())---- 一.拖拽 draggable=ture-----A拖动元素上事件 1. 拖拽开始:ondragstart2. 拖拽中:ondrag3. 拖拽结 ...
- Codeforces 679A Bear and Prime 100
链接:传送门 题意:给你一个隐藏数,这个隐藏数在[2,100]之间,现在最多可以询问20次,每次询问的是这个数是不是隐藏数的底数,是为yes,不是为no,每次询问后都需要flush一下输出缓冲区,最后 ...
- Eigen下载安装
首先提供Eigen的两个重要网站 官方网站 下载地址 1.下载 wget http://bitbucket.org/eigen/eigen/get/3.3.5.tar.gz 2.解压缩 tar -zx ...
- python--(常用模块-2序列化)
python--(常用模块-2序列化) 一.序列化: 把对象打散成bytes或者字符串. 方便存储和传输 序列化 把bytes或者字符串转换回对象. 反序列化 # dumps 序列化. 把对象转化成b ...
- 洛谷 P1029 最大公约数和最小公倍数问题
有两种做法 一种是gcd与lcm相乘后就是两个数的乘积,枚举第一个数,算出第二数,看最大公约数是不是题目给的. 第二种就lcm/gcd的答案为两个互质的数相乘.然后就枚举有多少组互质的数相乘等于lcm ...
- tcpdump的使用以及参数详解
平时分析客户端和服务器网络交互的问题时,很多情况下需要在客户端和服务器抓包分析报文.一般win下抓包使用WireShark即可,但是linux下就需要用到tcpdump了,下面是一些对于tcpdump ...
- 【 【henuacm2016级暑期训练】动态规划专题 K】 Really Big Numbers
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 会发现如果x是reallynumber那么x+1也会是reallynumber.... (个位数+1,各位数的和+1了但是整个数也+ ...