您将获得一个包含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. c++primer-p100.用迭代器进行二分法搜索

    #include <vector> #include <iostream> using namespace std; int main() { vector<int> ...

  2. hibernate学习笔记(1)基础配置与jar包

    下载hibernate基础jar包,并解压hibernate-core-4.2.4.final 在myeclipse中添加hibernate的dtd支持: location为D:\学习\imooc-h ...

  3. Jsonp实现跨域请求Ajax

    客户端 #!/usr/bin/env python import tornado.ioloop import tornado.web class MainHandler(tornado.web.Req ...

  4. fragment界面交互实操(步骤)

    首先,新建一个继承了fragment类的类,在oncreateview方法中,使用方法的参数inflater,用其inflater.inflate(R.layout.fragment1,contain ...

  5. Border Layout

    ------------------siwuxie095                             根面板 contentPane 的默认布局就是 Border Layout     B ...

  6. Swing界面组件的通用属性

    ----------------siwuxie095                             Swing 界面组件(控件)的通用属性:         (1)enabled:启用/禁用 ...

  7. 阿里云、宝塔、wordpress建站

    1 阿里云 购买一个学生机就行啦 2 宝塔 2.1 更改阿里云的镜像 技巧01:先关掉阿里云之前的镜像 技巧02:到镜像市场中寻找宝塔的镜像资源 2.2 配置安全组 宝塔的控制面板需要开通端口 888 ...

  8. Ajax01 什么是ajax、获取ajax对象、ajax对象的属性和方法、编程步骤、缓存问题、乱码问题

    目录 1 什么是ajax 2 获取ajax对象 3 ajax对象的属性和方法 4 使用ajax的编程步骤 5 缓存问题 6 乱码问题 1 什么是ajax ajax是一种用来改善用户体验的技术,其本质是 ...

  9. jquery easyui datagrid/table 右边线显示不全

    <table id="dg" style="height:400px"></table> 右边线显示不全 解决:在外面套一个panel, ...

  10. 算法Sedgewick第四版-第1章基础-2.3 Quicksort-001快速排序

    一. 1.特点 (1)The quicksort algorithm’s desirable features are that it is in-place (uses only a small a ...