主席树放到树上而已

#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
int n, m, lstans, uu, vv, a[100005], b[100005], rnk[100005], rem, cnt;
int lson[2200005], rson[2200005], sum[2200005], rot[100005], qwq, ww;
int fa[100005][19], dep[100005], hea[100005], tt[5];
struct Edge{
int too, nxt;
}edge[200005];
void add_edge(int fro, int too){
edge[++qwq].nxt = hea[fro];
edge[qwq].too = too;
hea[fro] = qwq;
}
int build(int l, int r){
int rt=++cnt;
int mid=(l+r)>>1;
if(l==r) return rt;
if(l<=mid) lson[rt] = build(l, mid);
if(mid<r) rson[rt] = build(mid+1, r);
return rt;
}
int update(int pre, int l, int r, int x){
int rt=++cnt;
int mid=(l+r)>>1;
lson[rt] = lson[pre]; rson[rt] = rson[pre]; sum[rt] = sum[pre] + 1;
if(l<r){
if(x<=mid) lson[rt] = update(lson[pre], l, mid, x);
if(mid<x) rson[rt] = update(rson[pre], mid+1, r, x);
}
return rt;
}
void dfs(int x, int f){
fa[x][0] = f;
dep[x] = dep[f] + 1;
rot[x] = update(rot[f], 1, rem, rnk[x]);
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t!=f) dfs(t, x);
}
}
int getLca(int uu, int vv){
if(dep[uu]<dep[vv]) swap(uu, vv);
for(int i=16; i>=0; i--)
if(dep[fa[uu][i]]>=dep[vv])
uu = fa[uu][i];
if(uu==vv) return vv;
for(int i=16; i>=0; i--)
if(fa[uu][i]!=fa[vv][i]){
uu = fa[uu][i];
vv = fa[vv][i];
}
return fa[uu][0];
}
int query(int l, int r, int k){
int tmp=0;
int mid=(l+r)>>1;
tmp -= sum[lson[tt[3]]] + sum[lson[tt[4]]];
tmp += sum[lson[tt[1]]] + sum[lson[tt[2]]];
if(l==r) return l;
if(k<=tmp){
for(int i=1; i<=4; i++)
tt[i] = lson[tt[i]];
return query(l, mid, k);
}
else{
for(int i=1; i<=4; i++)
tt[i] = rson[tt[i]];
return query(mid+1, r, k-tmp);
}
}
int main(){
cin>>n>>m;
for(int i=1; i<=n; i++){
scanf("%d", &a[i]);
b[i] = a[i];
}
for(int i=1; i<n; i++){
scanf("%d %d", &uu, &vv);
add_edge(uu, vv);
add_edge(vv, uu);
}
sort(b+1, b+1+n);
rem = unique(b+1, b+1+n) - (b + 1);
for(int i=1; i<=n; i++)
rnk[i] = lower_bound(b+1, b+1+rem, a[i]) - b;
rot[0] = build(1, rem);
dfs(1, 0);
for(int i=1; i<=16; i++)
for(int j=1; j<=n; j++)
fa[j][i] = fa[fa[j][i-1]][i-1];
while(m--){
scanf("%d %d %d", &uu, &vv, &ww);
uu ^= lstans;
int lca=getLca(uu, vv);
tt[1] = rot[uu]; tt[2] =rot[vv];
tt[3] = rot[lca]; tt[4] = rot[fa[lca][0]];
lstans = b[query(1, rem, ww)];
printf("%d\n", lstans);
}
return 0;
}

最新文章

  1. SPRING多个占位符配置文件解析源码研究--转
  2. good design
  3. oracle 表类型变量的使用
  4. 转载--redis密码管理
  5. sqlmap用户手册详解(转)
  6. 【OpenCV新手教程之十二】OpenCV边缘检測:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑
  7. http学习笔记(3)
  8. Django学习日记04_模板_overview
  9. BZOJ_3261_最大异或和_可持久化trie
  10. 快照(Snapshot)技术发展综述
  11. python assert的用处
  12. 浅析foreach语句
  13. 玩游戏 学Flex布局
  14. 软件工程(FZU2015) 赛季得分榜,第二回合
  15. python--异常捕获
  16. 《转载》python爬虫实践之模拟登录
  17. 2018/04/25 PHP7的编译安装
  18. python小数据池,代码块知识
  19. MERGE INTO 解决大数据量 10w 更新缓慢的问题
  20. js 开源k线图开发库

热门文章

  1. Python之单元测试——HTMLTestRunner
  2. 492 Construct the Rectangle 构建矩形
  3. 一个因xdata声明引起的隐含错误
  4. JAVA字符串转日期或日期转字符串【转】
  5. IIS6配置FastCGI遇到ERROR5的解决方法
  6. springboot之项目打包
  7. 备忘录模式及php实现
  8. Mac上安装Homebrew和wget
  9. 李开复:AlphaGo 若打败了世界冠军,意味着什么?
  10. 基础数据类型(set集合)