您将获得一个包含N个节点的树。树节点的编号从1到Ñ。每个节点都有一个整数权重。

我们会要求您执行以下操作:

  • uvk:询问从节点u到节点v的路径上的第k个最小权重

输入

在第一行中有两个整数Ñ和中号。(N,M <= 100000)

在第二行中有N个整数。第i个整数表示第i个节点的权重。

在接下来的N-1行中,每行包含两个整数u v,它描述了一个边(u,v)。

在接下来的M行中,每行包含三个整数u v k,这意味着要求从节点u到节点v的路径上的第k个最小权重的操作。

解题思路:
首先对于求第K小的问题 我们可以用主席树搞 ,没有问题,
但是对于一个树形结构,我们需要将其转化为线性,然后需要树剖才能做.

然后考虑链上的第k值怎么维护 ,
发现如果树剖计算的话 维护不了啊
因为(u,v)的路 可能在很多个链上,那么不能对每个求第K值,这样明显是错误的啊,

然后我们知道主席树其实就是维护了一个前缀和

那么我们可以对每一个节点到根节点建立前缀和,就能找任意一个节点到根节点的第K值,
那么根据主席树的性质,我们就能够计算(u,v)的路上的第K值了
只要在查询的时候稍改变一下就行了

cnt = sum[ls[u]]+sum[ls[v]]-sum[ls[lca(u,v)]]-sum[ls[fa[lca(u,v)]]];

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<map>
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+;
typedef long long LL;
int rt[N*], ls[N*], rs[N*], sum[N*];
int fa[*N][], dep[*N], vis[N];
int a[N], b[N], tot, cnt, head[N], len;
struct node
{
int to, next;
} p[*N];
void init()
{
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
cnt=;
return ;
}
void add(int u,int v)
{
p[cnt].to=v,p[cnt].next=head[u];head[u]=cnt++;
p[cnt].to=u,p[cnt].next=head[v];head[v]=cnt++;
return ;
}
void build(int &o,int l,int r)
{
o= ++tot,sum[o]=;
if(l==r) return ;
int mid=(l+r)/;
build(ls[o],l,mid);
build(rs[o],mid+,r);
return ;
}
void update(int &o,int l,int r,int last,int p)
{
o= ++tot;
ls[o]=ls[last],rs[o]=rs[last];
sum[o]=sum[last]+;
if(l==r) return ;
int mid=(l+r)/;
if(p<=mid) update(ls[o],l,mid,ls[last],p);
else update(rs[o],mid+,r,rs[last],p);
return ;
}
int query(int ss,int tt,int s1,int t1,int l,int r,int cnt)
{
if(l==r) return l;
int tmp=sum[ls[tt]]+sum[ls[ss]]-sum[ls[s1]]-sum[ls[t1]];
int mid=(l+r)/;
if(tmp>=cnt) return query(ls[ss],ls[tt],ls[s1],ls[t1],l,mid,cnt);
else return query(rs[ss],rs[tt],rs[s1],rs[t1],mid+,r,cnt-tmp);
}
void dfs(int u,int d,int f,int root)
{
vis[u]=,dep[u]=d,fa[u][]=f;
update(rt[u],,len,root,a[u]);
root=rt[u];
for(int i=head[u];i!=-;i=p[i].next)
{
int v=p[i].to;
if(vis[v]) continue;
dfs(v,d+,u,root);
}
return ;
}
void lca(int n)
{
int k=(int)(log(1.0*n)/log(2.0));
for(int i=;i<=k;i++)
{
for(int j=;j<=n;j++)
{
fa[j][i]=fa[fa[j][i-]][i-];
}
}
return ;
}
int get(int x,int y,int n)
{
if(dep[x]<dep[y]) swap(x,y);
int k=(int)(log(1.0*n)/log(2.0));
int d=dep[x]-dep[y];
for(int i=;i<=k;i++)
if((d&(<<i))) x=fa[x][i];
if(x==y) return x;
for(int i=k;i>=;i--)
{
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
}
return fa[x][];
} int main()
{
int t, n, q;
scanf("%d %d", &n, &q);
for(int i=; i<=n; i++) scanf("%d", &a[i]), b[i]=a[i];
sort(b+,b+n+);
len=unique(b+,b+n+)-(b+);
tot=;
build(rt[],,len);
for(int i=; i<=n; i++) a[i]=lower_bound(b+,b+len+,a[i])-(b);
init();
for(int i=;i<n-;i++)
{
int x, y;
scanf("%d %d", &x, &y);
add(x,y);
}
dfs(,,,rt[]);
lca(n);
while(q--)
{
int l, r, x;
scanf("%d %d %d", &l, &r, &x);
int pos=get(l,r,n);
printf("%d\n",b[query(rt[l],rt[r],rt[pos],rt[fa[pos][]],,len,x)]);
}
return ;
}
 

spoj COT - Count on a tree(主席树 +lca,树上第K大)的更多相关文章

  1. 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

  2. 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 ...

  3. BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca

    分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...

  4. BZOJ.2588.Count on a tree(主席树 静态树上第k小)

    题目链接 /* 序列上的主席树 某点是利用前一个点的根建树 同理 树上的主席树 某个节点可以利用其父节点(is unique)的根建树 排名可以利用树上前缀和求得: 对于(u,v),w=LCA(u,v ...

  5. 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  ...

  6. 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 ...

  7. HDU 4729 An Easy Problem for Elfness (主席树,树上第K大)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一个带边权的图.对于每一个询问(S , ...

  8. SP10628 COT - Count on a tree 主席树

    Code: #include<cstdio> #include<cstring> #include<algorithm> #include<string> ...

  9. [bzoj2588][count on a tree] (主席树+lca)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

随机推荐

  1. pthon之函数式编程

    函数式编程是一种抽象计算的编程范式. 不同语言的抽象层次不同:计算机硬件->汇编语言->C语言->Python语言 指令        ->           ->函数 ...

  2. MyBatis总结七:动态sql和sql片段

    开发中,sql拼接很常见,所以说一下动态sql: 1 if 2 chose,when,otherwise 3 where,set 4 foreach 用法解析(现有一张users表 内有id user ...

  3. Centos彻底完全删除已安装软件的办法

    1.查询是否安装了软件 rpm -qa | grep -i 软件名 rpm -qa | grep php 2.删除已安装的软件包 根据第一步显示的软件包名,一个个删除 sudo rpm -e -- 包 ...

  4. Boost 线程学习笔记

    Bolg转载自:http://www.cnblogs.com/lvdongjie/p/4447193.html 一: 创建线程 #include <iostream> #include & ...

  5. c语言学习笔记-变量、变量的命名、变量的赋值和变量的初始化

    在学习了简单的输入输出功能和了解了一些基本的运算符号之后我们可以试着做一个非常简单的计算器. 比如说想计算23+65 输入以下代码就可以了. printf("23+65=%d",2 ...

  6. 算法Sedgewick第四版-第1章基础-003一封装日期

    1. package ADT; import algorithms.util.StdOut; /**************************************************** ...

  7. 数字图像处理实验(2):PROJECT 02-02, Reducing the Number of Gray Levels in an Image 标签: 图像处理MATLAB 2017-

    实验要求: Reducing the Number of Gray Levels in an Image Objective To understand how the number of gray ...

  8. AR# 30522:LogiCORE RapidIO - How do system_reset and link_reset work?

    Description How do system_reset and link_rest work? Solution lnk_linkreset_n (input): In Xilinx SRIO ...

  9. 解决Spring MVC 对AOP不起作用的问题

    用的是 SSM3的框架 Spring MVC 3.1 + Spring 3.1 + Mybatis3.1 第一种情况: Spring MVC 和 Spring 整合的时候,SpringMVC的spri ...

  10. jmeter beanShell 修改http请求参数

    转自http://www.tuicool.com/articles/rEri63   http://powertech.iteye.com/blog/2174521 主题 HTTPJMeter 在使用 ...