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 N. Each node has an integer weight.
We will ask you to perform the following operation:
- u v k : ask for the kth minimum weight on the path from node u to node v
Input
In the first line there are two integers N and M. (N, M <= 100000)
In the second line there are N integers. The ith integer denotes the weight of the ith node.
In the next N-1 lines, each line contains two integers u v, which describes an edge (u, v).
In the next M lines, each line contains three integers u v k, which means an operation asking for the kth minimum weight on the path from node u to node v.
Output
For each operation, print its result.
Example
Input: 8 5 105 2 9 3 8 5 7 7 1 2 1 3 1 4 3 5 3 6 3 7 4 82 5 12 5 22 5 32 5 47 8 2
Output: 2891057 题目链接:http://www.spoj.com/problems/COT/二、思路 原理其实和一维线性表序列的一样。只不过这是在树上操作。 在一维线性表序列中,扫描序列中每一个离散化后的数字,每一次新建的权值线段树都是基于前一次的。而在树中,对每一个子节点的数字,新建的线段树都是基于父节点的线段树的。
***************************未完待续……
***************************
三、源代码
#pragma GCC optimize(2)
#pragma comment(linker, "/STACK:102400000, 102400000")
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define MAXN 111111
LL n, q, m;
/*************树部分*******************/
typedef struct {
int to, next;
} Edge;
Edge tree[MAXN * ];
int head[MAXN], ecnt;
void add(int from, int to) {
tree[ecnt].to = to;
tree[ecnt].next = head[from];
head[from] = ecnt++;
}
/*************树部分*******************/
/*************LCA部分*******************/
], depth[MAXN];
void dfs4lca(int r, int par, int d) {
parent[r][] = par, depth[r] = d;
; i = tree[i].next) {
int to = tree[i].to;
if(to != par)
dfs4lca(to, r, d + );
}
}
void init4lca() {
dfs4lca(, -, );
; k < ; ++k) {
; v <= n; ++v) {
)
parent[v][k + ] = -;
else
parent[v][k + ] = parent[parent[v][k]][k];
}
}
}
int lca(int a, int b) {
if(depth[a] < depth[b])
swap(a, b);
; i < ; ++i) {
)
a = parent[a][i];
}
if(a == b)
return a;
; i >= ; --i) {
if(parent[a][i] != parent[b][i]) {
a = parent[a][i];
b = parent[b][i];
}
}
];
}
/*************LCA部分*******************/
/*************主席树部分*******************/
struct {
int lch, rch, cnt;
} nodes[MAXN * ];
int root[MAXN], ncnt;
, int r = m) {
if(!nroot) {
nroot = ++ncnt;
nodes[nroot].cnt = nodes[proot].cnt + ;
}
if(l == r)
return;
;
if(val <= mid) {
nodes[nroot].rch = nodes[proot].rch;
update(nodes[nroot].lch, nodes[proot].lch, val, l, mid);
} else {
nodes[nroot].lch = nodes[proot].lch;
update(nodes[nroot].rch, nodes[proot].rch, val, mid + , r);
}
}
, int r = m) {
if(l == r)
return l;
int cnt = nodes[nodes[uroot].lch].cnt + nodes[nodes[vroot].lch].cnt
- nodes[nodes[lcaroot].lch].cnt - nodes[nodes[lcafroot].lch].cnt;
;
if(k <= cnt)
return query(nodes[uroot].lch, nodes[vroot].lch, nodes[lcaroot].lch, nodes[lcafroot].lch, k, l, mid);
else
, r);
}
/*************主席树部分*******************/
/*************离散化部分*******************/
LL weight[MAXN], buf[MAXN], mp[MAXN];
int nwt[MAXN];
void discrete() {
memcpy(buf + , weight + , ]) * n);
sort(buf + , buf + n + );
m = unique(buf + , buf + n + ) - buf - ;
; i <= n; ++i) {
nwt[i] = lower_bound(buf + , buf + m + , weight[i]) - buf;
mp[nwt[i]] = weight[i];
}
}
/*************离散化部分*******************/
template <class T> inline void read(T &x) {
int t;
bool flag = false;
')) ;
if(t == '-')
flag = true, t = getchar();
x = t - ';
')
x = x * + t - ';
if(flag)
x = -x;
}
void init() {
memset(head, -, sizeof(head));
ecnt = ;
//nodes = 0, root = 0, ncnt = 0;
}
void dfs4tree(int r, int par) {
; i = tree[i].next) {
int to = tree[i].to;
if(to != par) {
update(root[to], root[r], nwt[to]);
dfs4tree(to, r);
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif // ONLINE_JUDGE
init();
LL a, b, u, v, k, wt, uvlca, ans;
scanf("%lld%lld", &n, &q);
; i <= n; ++i) {
read(weight[i]);
}
; i < n; ++i) {
read(a), read(b);
add(a, b);
add(b, a);
}
init4lca();
discrete();
add(, );//添加一条虚边。
dfs4tree(, -);
while(q--) {
read(u), read(v), read(k);
uvlca = LL(lca(u, v));
ans = mp[query(root[u], root[v], root[uvlca], root[parent[uvlca][]], int(k))];
printf("%lld\n", ans);
}
;
}
SPOJ Count on a tree(主席树+LCA)的更多相关文章
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...
- spoj COT - Count on a tree(主席树 +lca,树上第K大)
您将获得一个包含N个节点的树.树节点的编号从1到Ñ.每个节点都有一个整数权重. 我们会要求您执行以下操作: uvk:询问从节点u到节点v的路径上的第k个最小权重 输入 在第一行中有两个整数Ñ和中号.( ...
- [bzoj2588][count on a tree] (主席树+lca)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- 洛谷P2633/bzoj2588 Count on a tree (主席树)
洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...
- 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 ...
- 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 ...
- 【BZOJ-2588】Count on a tree 主席树 + 倍增
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 3749 Solved: 873[ ...
- 洛谷P2633 Count on a tree(主席树上树)
题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...
随机推荐
- fiddler抓包https
http://blog.csdn.net/idlear/article/details/50999490 charles也能抓取https请求 http://blog.csdn.net/jiadoud ...
- 51nod 1225 余数的和 数学
1225 余数之和 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 F(n) = (n % 1) + (n % 2) + (n % 3) + ... ...
- MVC结构之Service概念
所有的逻辑都放到M层,M层会臃肿. 所有的逻辑都放到C层,C层会臃肿. 这个时候需要一个中间层,Service层. Service可以倾向于Model层,比如处理订单查询相关的逻辑. Service可 ...
- 教你上传代码到码云(与github一样)
以下所有操作都在命令行进行 1 git 配置 git config --global user.name “用户名” git config --global user.email “邮箱”2 生成公钥 ...
- bzoj2705: [SDOI2012]Longge的问题 欧拉定理
题意:给定一个整数N,你需要求出∑gcd(i, N)(1<=i <=N). 题解:考虑n的所有因子,假设有因子k,那么对答案的贡献gcd(i,n)==k的个数即gcd(i/k,n/k)== ...
- 最小生成树prim和kruskal模板
prim: int cost[MAX_V][MAX_V]; //cost[u][v]表示边e=(u,v)的权值(不存在的情况下设为INF) int mincost[MAX_V]; //从集合X出发的每 ...
- OAF TABLE中第一列添加事件不生效
我遇到一个比较诡异的现象 在TABLE中,我在TABLE的第一列添加了一个MessageCheckBox,并为其设置全局刷新的FireAction事件selection, 但是点击勾选框按钮之后,事件 ...
- IOS UI-QQ好友列表
一.Model // // FriendsModel.h // IOS_0111_好友列表 // // Created by ma c on 16/1/11. // Copyright (c) 201 ...
- linux 命令-case
case 命令作用: case语句使用于需要进行多重分支的应用情况 case 命令使用场景 在shell中的case结构与C/C++中的switch结构是相同的. 它允许通过判断来选择代码块中多条路径 ...
- 认识Applet和Ajax
一.Applet 1.Applet的定义:Applet是采用Java编程语言编写的小应用程序,该程序可以包含在HTML(标准通用标记语言的一个应用)页中,与在页中包含图像的方式大致相同. Java写出 ...