n<=100000的点权树,有m<=100000个询问,每次问两个点间的第k小点权,保证有解,强制在线。

主席上树啦!类似于之前的序列不带修改询问的前缀表示法,现在只要把前缀当成某点到根的信息即可。然后比如要问x点和y点,z为lca(x,y),w为z的爸爸,那么x,y,z,w四棵线段树一起跑即可。

 #include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
//#include<iostream>
using namespace std; int n,m;
#define maxn 100011
#define maxm 2000011
struct SMT
{
struct Node
{
int son[];
int cnt;
}a[maxm];
int size,n;
void clear(int m) {n=m;size=;a[].cnt=;}
void build(int pre,int &rt,int L,int R,int num)
{
rt=++size;
a[rt].cnt=a[pre].cnt+;
if (L==R) {a[rt].son[]=a[rt].son[]=;return;}
const int mid=(L+R)>>;
if (num<=mid) build(a[pre].son[],a[rt].son[],L,mid,num),a[rt].son[]=a[pre].son[];
else build(a[pre].son[],a[rt].son[],mid+,R,num),a[rt].son[]=a[pre].son[];
}
void build(int pre,int &rt,int num) {build(pre,rt,,n,num);}
// void test(int x,int L,int R)
// {
// const int mid=(L+R)>>1;
// if (a[x].son[0]) test(a[x].son[0],L,mid);
//// cout<<L<<' '<<R<<' '<<a[x].cnt<<endl;
// if (a[x].son[1]) test(a[x].son[1],mid+1,R);
// }
// void test(int x) {test(x,1,n);}
}smt; struct Edge{int to,next;}edge[maxn<<];int first[maxn],le=;
void in(int x,int y) {Edge &e=edge[le];e.to=y;e.next=first[x];first[x]=le++;}
void insert(int x,int y) {in(x,y);in(y,x);} int a[maxn],b[maxn],lb;
int fa[maxn][],dep[maxn],rt[maxn];
void dfs(int x,int f)
{
fa[x][]=f;dep[x]=dep[f]+;
for (int j=;j<=;j++)
fa[x][j]=fa[fa[x][j-]][j-];
smt.build(rt[f],rt[x],a[x]);
for (int i=first[x];i;i=edge[i].next)
{
const Edge &e=edge[i];if (e.to==f) continue;
dfs(e.to,x);
}
}
void pre() {dfs(,);} int lca(int x,int y)
{
if (dep[x]<dep[y]) {int t=x;x=y;y=t;}
for (int i=;i>=;i--) if (dep[fa[x][i]]>=dep[y]) x=fa[x][i];
if (x==y) return x;
for (int i=;i>=;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][];
} int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
lb=n;sort(b+,b++lb);lb=unique(b+,b++lb)-b-;
for (int i=;i<=n;i++) a[i]=lower_bound(b+,b++lb,a[i])-b; smt.clear(lb);
for (int i=,x,y;i<n;i++)
{
scanf("%d%d",&x,&y);
insert(x,y);
}
pre();
// for (int i=1;i<=n;i++) smt.test(rt[i]),cout<<endl;
int last=;
for (int i=,x,y,K;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&K);
x^=last;
int z=lca(x,y),w=fa[z][],L=,R=lb,tmp;
// cout<<x<<' '<<y<<' '<<z<<' '<<w<<endl;
x=rt[x];y=rt[y];z=rt[z];w=rt[w];
while (L<R)
{
if ((tmp=smt.a[smt.a[x].son[]].cnt+smt.a[smt.a[y].son[]].cnt
-smt.a[smt.a[z].son[]].cnt-smt.a[smt.a[w].son[]].cnt)>=K)
x=smt.a[x].son[],y=smt.a[y].son[],z=smt.a[z].son[],w=smt.a[w].son[],R=(L+R)>>;
else x=smt.a[x].son[],y=smt.a[y].son[],z=smt.a[z].son[],w=smt.a[w].son[],K-=tmp,L=((L+R)>>)+;
// cout<<tmp<<' '<<K<<endl;
}
printf("%d",(last=b[L]));
if (i<m) puts("");
}
return ;
}

主席树初探--BZOJ2588: Spoj 10628. Count on a tree的更多相关文章

  1. 【主席树】bzoj2588 Spoj 10628. Count on a tree

    每个点的主席树的root是从其父转移来的.询问的时候用U+V-LCA-FA(LCA)即可. #include<cstdio> #include<algorithm> using ...

  2. BZOJ2588: Spoj 10628. Count on a tree

    传送门 刚开始看错题以为是dfs序瞎搞.. 后来看清题了开始想用树剖瞎搞... 感觉要滚粗啊.. 对于每个点到根的路径建立线段树,暴力建MLE没跑,上主席树,然后$(x,y)$的路径就可以先求出来$L ...

  3. bzoj2588: Spoj 10628. Count on a tree(树上第k大)(主席树)

    每个节点继承父节点的树,则答案为query(root[x]+root[y]-root[lca(x,y)]-root[fa[lca(x,y)]]) #include<iostream> #i ...

  4. 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA

    [BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...

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

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

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

  8. 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个节点的树,每个点 ...

  9. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

随机推荐

  1. LN : leetcode 312 Burst Balloons

    lc 312 Burst Balloons 312 Burst Balloons Given n balloons, indexed from 0 to n-1. Each balloon is pa ...

  2. bootstrap基本布局

    中文API bootstrap.cn   HTML5文档 类型   移动设备优先 width 属性控制设备的宽度.设置为 device-width 确保它能正确呈现在不同设备上. initial-sc ...

  3. CSS——BFC

    http://www.cnblogs.com/lhb25/p/inside-block-formatting-ontext.html 元素若不是bfc,那么内部浮动元素的高度不参与计算 元素若不是bf ...

  4. SQL 索引自动维护计划脚本

    脚本功能: 1,查询数据库中,碎片率在5%以上(官方推荐),有一定数据里的表的索引. 2.如果碎片率在5%<碎片率<=30%  执行重新组织索引.如果在30%以上,执行重建索引 建议在执行 ...

  5. 迅为电子4.3寸CAN总线工业平板电脑简介

    型号:iTOP-HMI043-C 4.3寸CAN总线工业平板电脑支持CAN通讯显示器,显示:显示尺寸:4.3英寸:分辨率:480×272 TFT液晶 65536色 :接口:支持CAN 2.0B:USB ...

  6. 引入msword

    找到解决方法了:不是直接引入mswork.tlh文件的,该文件是#import "C:\\Program Files\\Microsoft Office\\Office12\\MSWORD. ...

  7. R-FCN:Object Detection via Region-based Fully Convolutional Networks

    fast.faster这些网络都可以被roi-pooling层分成两个子网络:1.a shared,'fully convolutional' subnetwork 2.an roi-wise sub ...

  8. 实训day01 python基础

    一.编程语言 编程语言:可以被计算机所识别的表达方式. 编程:程序员通过编程语言将自己的想法编写出来,产生的结果就是包含字符的文件. 其中,只有程序在运行时,其中的字符才有特定的语法意义. 二.计算机 ...

  9. 2019年,Linux运维行业的趋势,跟不上学习就被淘汰

    运维行业经历了多年的发展,已经有了很大的变化,最开始的机房.网线.人肉,到现在一步步的自动化.智能化.容器化,运维人员的职业技能要求越来越高,稍不注意就可能被淘汰. 今天马小哥就来盘点一下2019年运 ...

  10. idea vue提示

    我在idea中,装了,vue.js插件,可就是死活,没有提示,我的html 文件是 .html扩展名,我想是不是因为这个原因,我就新建了个,test.vue,哈哈,提示出来了,我又在其它.html文件 ...