主席树上树,对于每个节点,继承其父亲的,最后跑f[x]+f[y]-f[lca]-f[fa[lca]]

去重竟然要减一,我竟然不知道??

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#define N 100005
using namespace std;
int e=1,head[N];
struct edge{
int u,v,next;
}ed[2*N];
void add(int u,int v){
ed[e].u=u;ed[e].v=v;
ed[e].next=head[u];
head[u]=e++;
} int root[2*N],sum[80*N],lon[80*N],ron[80*N],sz;
int dep[2*N],fa[2*N][18],n,m,v[2*N],num[2*N],num_cnt; void print(int rt,int l,int r){
if(!rt) return;
printf("%d %d %d %d %d %d\n",rt,l,r,lon[rt],ron[rt],sum[rt]);
int mid=(l+r)>>1;
print(lon[rt],l,mid);
print(ron[rt],mid+1,r);
}
void update(int p,int &rt,int l,int r,int x){
rt=++sz;
sum[rt]=sum[p]+1;
if(l==r) return;
lon[rt]=lon[p]; ron[rt]=ron[p];
int mid=(l+r)>>1;
if(x<=mid) update(lon[p],lon[rt],l,mid,x);
else update(ron[p],ron[rt],mid+1,r,x);
} void dfs(int x){
for(int i=1;i<=17;i++)
if((1<<i)<=dep[x])
fa[x][i]=fa[fa[x][i-1]][i-1];
else break;
update(root[fa[x][0]],root[x],1,num_cnt,v[x]);
for(int i=head[x];i;i=ed[i].next){
int v=ed[i].v;
if(v==fa[x][0]) continue;
dep[v]=dep[x]+1; fa[v][0]=x;
dfs(v);
}
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
int t=dep[x]-dep[y];
for(int i=17;~i;i--)
if(t&(1<<i))
x=fa[x][i];
if(x==y)return x;
for(int i=17;~i;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
} int query(int x,int y,int k){
int ca=lca(x,y);
int a=root[x],b=root[y],c=root[ca],d=root[fa[ca][0]];
int l=1,r=num_cnt;
while(l<r){
int mid=(l+r)/2;
int tmp=sum[lon[a]]+sum[lon[b]]-sum[lon[c]]-sum[lon[d]];
if(tmp>=k){r=mid;a=lon[a];b=lon[b];c=lon[c];d=lon[d];/*printf("666\n");*/}
else{k-=tmp;l=mid+1;a=ron[a];b=ron[b];c=ron[c];d=ron[d];}
}
//printf("l==%d\n",l);
return num[l];
}
int main()
{
int U,V,kth;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&v[i]);
num[i]=v[i];
}
sort(num+1,num+n+1);
num_cnt=unique(num+1,num+n+1)-num-1;
for(int i=1;i<=n;i++)
v[i]=lower_bound(num+1,num+num_cnt+1,v[i])-num;
for(int i=1;i<n;i++){
scanf("%d%d",&U,&V);
add(U,V); add(V,U);
}
dep[0]=-1;
dfs(1);
int ans=0;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&U,&V,&kth);
U^=ans;
ans=query(U,V,kth);
printf("%d",ans);
if(i<m) printf("\n");
}
return 0;
}

bzoj 2588 树上主席树的更多相关文章

  1. SPOJ COT Count on a tree(树上主席树 + LCA 求点第k小)题解

    题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...

  2. p3302 [SDOI2013]森林(树上主席树+启发式合并)

    对着题目yy了一天加上看了一中午题解,终于搞明白了我太弱了 连边就是合并线段树,把小的集合合并到大的上,可以保证规模至少增加一半,复杂度可以是\(O(logn)\) 合并的时候暴力dfs修改倍增数组和 ...

  3. 【洛谷2633】Count on a tree(树上主席树)

    点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...

  4. Count on a tree 树上主席树

    Count on a tree 树上主席树 给\(n\)个树,每个点有点权,每次询问\(u,v\)路径上第\(k\)小点权,强制在线 求解区间静态第\(k\)小即用主席树. 树上主席树类似于区间上主席 ...

  5. [CSP-S模拟测试]:e(树上主席树)

    题目传送门(内部题66) 输入格式 第一行,一个正整数$n$,一个自然数$q$,一个整数$type$.第二行,$n$个正整数,代表$a_i$.接下来$n-1$行,每行两个正整数$u$.$v$,代表树中 ...

  6. bzoj3123 [Sdoi2013]森林 树上主席树+启发式合并

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3123 题解 如果是静态的查询操作,那么就是直接树上主席树的板子. 但是我们现在有了一个连接两棵 ...

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

  8. 【学术篇】SPOJ COT 树上主席树

    这是学完主席树去写的第二道题_(:з」∠)_ 之前用树上莫队水过了COT2... 其实COT也可以用树上莫队水过去不过好像复杂度要带个log还是怎么样可能会被卡常数.. 那就orz主席吧.... 写了 ...

  9. ☆ [洛谷P2633] Count on a tree 「树上主席树」

    题目类型:主席树+\(LCA\) 传送门:>Here< 题意:给出一棵树.每个节点有点权.问某一条路径上排名第\(K\)小的点权是多少 解题思路 类似区间第\(K\)小,但放在了树上. 考 ...

随机推荐

  1. Unity使用C++作为游戏逻辑脚本的研究(二)

    文章申明:本文来自JacksonDunstan的博客系列文章内容摘取和翻译,版权归其所有,附上原文的链接,大家可以有空阅读原文:C++ Scripting( in Unity) 上一篇文章写完,有同学 ...

  2. Spring 框架的优点及缺点

    首先Spring 是一个框架,使用Spring并不代表代码质量的提高,就像盖房子选择用上海的地皮还是北京的地皮一样,房子质量与土地所在的城市无关,与房子的具体设计方案和选料有关. 使用Spring 等 ...

  3. Memcache 运行情况

    Memcache Memcache是danga.com的一个开源项目,它是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的Hash表,能够用来存储各种格式的数据. 查看当前的me ...

  4. tarjan算法讲解。

    tarjan算法讲解.   全网最详细tarjan算法讲解,我不敢说别的.反正其他tarjan算法讲解,我看了半天才看懂.我写的这个,读完一遍,发现原来tarjan这么简单! tarjan算法,一个关 ...

  5. Spring中的循环依赖

    循环依赖 在使用Spring时,如果主要采用基于构造器的依赖注入方式,则可能会遇到循环依赖的情况,简而言之就是Bean A的构造器依赖于Bean B,Bean B的构造器又依赖于Bean A.在这种情 ...

  6. 深入理解Java NIO

    初识NIO: 在 JDK 1. 4 中 新 加入 了 NIO( New Input/ Output) 类, 引入了一种基于通道和缓冲区的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存 ...

  7. Lucene入门简介

    一  Lucene产生的背景 数据库中的搜索很容易实现,通常都是使用sql语句进行查询,而且能很快的得到查询结果. 为什么数据库搜索很容易? 因为数据库中的数据存储是有规律的,有行有列而且数据格式.数 ...

  8. tomcat第一次使用正常启动后访问8080端口报404错误

    问题:tomcat第一次使用正常启动后访问8080端口报404错误 解决办法:双击tomcat调出tomcat的xml文件页面,Server Locations 默认是选第一行即Use Workspa ...

  9. select case when与IF的用法

    case when概述 sql语句中的case语句与高级语言中的switch语句,是标准sql的语法,适用于一个条件判断有多种值的情况下分别执行不同的操作. case when示例 有一张表,里面有3 ...

  10. HTTP认证方式详解

    HTTP请求报头: Authorization HTTP响应报头: WWW-Authenticate   HTTP认证 基于 质询 /回应( challenge/response)的认证模式.   ◆ ...