spoj COT - Count on a tree(主席树 +lca,树上第K大)
您将获得一个包含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大)的更多相关文章
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- 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: Spoj 10628. Count on a tree 主席树+lca
分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...
- BZOJ.2588.Count on a tree(主席树 静态树上第k小)
题目链接 /* 序列上的主席树 某点是利用前一个点的根建树 同理 树上的主席树 某个节点可以利用其父节点(is unique)的根建树 排名可以利用树上前缀和求得: 对于(u,v),w=LCA(u,v ...
- 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: 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 ...
- HDU 4729 An Easy Problem for Elfness (主席树,树上第K大)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题意:给出一个带边权的图.对于每一个询问(S , ...
- SP10628 COT - Count on a tree 主席树
Code: #include<cstdio> #include<cstring> #include<algorithm> #include<string> ...
- [bzoj2588][count on a tree] (主席树+lca)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
随机推荐
- hive删除表报错:Specified key was too long; max key length&nb
我是在hive删除表的时候出现这个错误的,看到这个错误应该就知道是字符集错误. 但是我用 alter database hive character set latin1; 这个命令将其改成拉丁之后 ...
- CentOS 6.3安装jdk(笔记整理)
1. 下载bin文件,切忌oracle上现在下载到的旧版本的jdk的bin都是网页(执行会报错,见本文最后的截图),他们需要登录oracle后才能下载,所以我这里的url是从googlecode里觅来 ...
- go语言linux环境配置
linux的设置方法:有4个环境变量需要设置:GOROOT.GOPATH.GOBIN以及PATH.需要设置到某一个profile文件中(~/.bash_profile(单一用户)或/etc/profi ...
- JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-009Polymorphic collections(@OneToMany(mappedBy = "user")、@ManyToOne、)
一.代码 1. package org.jpwh.model.inheritance.associations.onetomany; import org.jpwh.model.Constants; ...
- Android 之 信息通知栏消息Notification
Notification是安卓手机顶部的消息提示 这里我们分别设置两个按钮,来实现顶部消息的发送和取消 功能实现 首先要在主Activity中设置一个通知控制类 NotificationManager ...
- Luogu 3530 [POI2012]FES-Festival
我是真的不会写差分约束啊呜呜呜…… BZOJ 2788被权限了. 首先对于第一个限制$x + 1 = y$,可以转化成$x + 1 \leq y \leq x + 1$, 所以连一条$(y, x, - ...
- 对Spark的理解
Spark作为一个新的分布式计算引擎正慢慢流行起来,越来越来的企业也准备用它的替换MapReduce,根据自己在工作的一些体会谈谈的优势. 分布式计算归根到底还是一个Map和Reduce操作,Map操 ...
- c# 汉字换英文,英文转汉字
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- 国内物联网平台(7):Ablecloud物联网自助开发和大数据云平台
国内物联网平台(7)——Ablecloud物联网自助开发和大数据云平台 马智 平台定位 面向IoT硬件厂商,提供设备联网与管理.远程查看控制.定制化云端功能开发.海量硬件数据存储与分析等基础设施,加速 ...
- SQLServer存储引擎——01.数据库如何读写数据
一.引言 在SQL Server数据库中,数据是如何被读写的?日志里都有些什么?和数据页之间是什么关系?数据页又是如何存放数据的?索引又是用来干嘛的? 一起看看SQL Server的存储引擎. 二.S ...