Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)
2588: Spoj 10628. Count on a tree
Time Limit: 12 Sec Memory Limit: 128 MB
Description
给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。
Input
第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v,k),表示一组询问。
Output
M行,表示每个询问的答案。最后一个询问不输出换行符
Sample Input
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
0 5 2
10 5 3
11 5 4
110 8 2
Sample Output
2
8
9
105
7
HINT:
N,M<=100000
暴力自重。。。
Source
鸣谢seter
/*
树上第K大.
对于每一个节点
以key为下标
用一颗权值线段树维护它到根的路径的区间K大值.
然后用主席树维护.
树剖求lca.
ans=tree[x].size+tree[y].size-tree[lca].size-tree[lca_father].size.
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#define MAXN 100001
using namespace std;
int n,m,ans,cut,maxsize,root[MAXN],tot,s[MAXN],a[MAXN],head[MAXN];
int fa[MAXN],pos[MAXN],top[MAXN],deep[MAXN],size[MAXN];
struct data{int lc,rc,size;}tree[MAXN*20];
struct node{int v,next;}e[MAXN*2];
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*f;
}
void add(int u,int v)
{
e[++cut].v=v;e[cut].next=head[u];head[u]=cut;
}
void add(int &k,int last,int l,int r,int x)
{
k=++tot;tree[k].lc=tree[last].lc,tree[k].rc=tree[last].rc;
tree[k].size=tree[last].size+1;
if(l==r) return ;
int mid=(l+r)>>1;
if(x<=mid) add(tree[k].lc,tree[last].lc,l,mid,x);
else add(tree[k].rc,tree[last].rc,mid+1,r,x);
return ;
}
void dfs1(int u,int f)
{
size[u]=1;
int p=lower_bound(s+1,s+n+1,a[u])-s;
add(root[u],root[f],1,n,p);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(v!=f) fa[v]=u,deep[v]=deep[u]+1,dfs1(v,u),size[u]+=size[v];
}
return ;
}
void dfs2(int u,int top1)
{
int k=0;pos[u]=++maxsize;top[u]=top1;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(fa[v]==u&&size[v]>size[k]) k=v;
}
if(!k) return ;
dfs2(k,top1);
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].v;
if(fa[v]==u&&v!=k) dfs2(v,v);
}
return ;
}
int lca(int x,int y)
{
fa[1]=1;
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) swap(x,y);//1 R.
x=fa[top[x]];
}
fa[1]=0;
if(pos[x]>pos[y]) swap(x,y);
return x;
}
int query(int L,int R,int lc,int falc,int l,int r,int k)
{
if(l==r) return l;
int mid=(l+r)>>1;
int sum=tree[tree[L].lc].size+tree[tree[R].lc].size-
tree[tree[lc].lc].size-tree[tree[falc].lc].size;
if(sum>=k)
return query(tree[L].lc,tree[R].lc,tree[lc].lc,tree[falc].lc,l,mid,k);
else return query(tree[L].rc,tree[R].rc,tree[lc].rc,tree[falc].rc,mid+1,r,k-sum);
}
void slovequery(int x,int y,int k)
{
int lc=lca(x,y);
ans=query(root[x],root[y],root[lc],root[fa[lc]],1,n,k);
printf("%d",ans=s[ans]);return ;
}
int main()
{
int x,y,z;
n=read(),m=read();
for(int i=1;i<=n;i++) s[i]=a[i]=read();
for(int i=1;i<=n-1;i++) x=read(),y=read(),add(x,y),add(y,x);
sort(s+1,s+n+1);dfs1(1,0),dfs2(1,1),fa[1]=0;
while(m!=1)
{
x=read(),y=read(),z=read();x^=ans;
slovequery(x,y,z);
m--;printf("\n");//2 W.
}
x=read(),y=read(),z=read();x^=ans;
slovequery(x,y,z);
return 0;
}
Bzoj 2588 Spoj 10628. Count on a tree(树链剖分LCA+主席树)的更多相关文章
- SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)
COT - Count on a tree #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 [树上主席树]
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 5217 Solved: 1233 ...
- BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树
2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...
- 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 ...
- BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
- bzoj 2588 Spoj 10628. Count on a tree (可持久化线段树)
Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 7669 Solved: 1894[Submi ...
- 主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree
题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y) ...
- BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...
- ●BZOJ 2588 Spoj 10628. Count on a tree
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2588 题解: 主席树,在线,(求LCA)感觉主席树真的好厉害...在原树上建主席树.即对于原 ...
随机推荐
- 如何自定义xml文件
在定义文件之前,首先要弄清楚什么是xml文件和dtd文件. 一:什么是xml文件? xml是一种可扩展标记性语言,标准通用标记语言的子集,是一种用于标记电子文件使其具有构造性的标记语言. 二:什么事d ...
- Docker 方式部署的应用的版本更新
前言 公司使用 Docker-Compose 的方式部署 Jenkins/Gitlab/Sonar/Confluence/Apollo/Harbor/ELK/MySQL 等一系列开发工具/数据库. 而 ...
- C++ 相关问题记录
目录 编译链接 使用初始化和使用赋值时,调用的函数不同:使用 auto_ptr() 时可能会出现编译错误 宏定义不受命名空间的约束 Switch-case 中不能定义变量 技巧/注意项 多层继承中基类 ...
- Redis 如何与数据库事务保持一致
考虑一个问题,redis 如何 与 数据库保持一致性的问题. 举栗子:如果我们在开发过程中遇到这样的一种情况,我们删除 redis中token 的同时 也需要修改数据库中 储存的 token 的状态为 ...
- Python通用爬虫,聚焦爬虫概念理解
通用爬虫:百度.360.搜狐.谷歌.必应....... 原理: (1)抓取网页 (2)采集数据 (3)数据处理 (4)提供检索服务 百度爬虫:Baiduspider 通用爬虫如何抓取新网站? (1)主 ...
- Python之数据处理-2
一.数据处理其实是一个很麻烦的事情. 在一个样本中存在特征数据(比如:人(身高.体重.出生年月.年龄.职业.收入...))当数据的特征太多或者特征权重小或者特征部分满足的时候. 这个时候就要进行数据的 ...
- sql语句中包含引号处理方法
1. 背景 在使用Python脚本向数据库导入日志文件时候,突然报错. 2. 解决思路 查看messages文件,发现有一条语句里包含单引号. 查看sql语句,是使用单引号标注str类型. 3. 得出 ...
- 【转载】C#中将字符串分割成字符数组
在C#中字符串类型String是由一系列的单个字符组合而成,其实可以通过字符串String对象ToCharArray()方法来将字符串中的元素逐一存在数据类型为Char的一维数组中. 例如将字符str ...
- English-培训1-Phonetic symbols
- ios设备app作为蓝牙外设端
苹果手机可以作为蓝牙外设端,被蓝牙中央端来扫描连接交互数据,实现模拟蓝牙外设硬件.通过阅读CoreBluetooth库,可以找到一个CBPeripheralManager的类,该类主要的作用就是允许你 ...