分析:树上第k小,然后我想说的是主席树并不局限于线性表

详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好,

然后因为这个熟悉了主席树,真是神器,强制在线,然后顺便学习了LCA倍增算法

LCA倍增算法是O(nlogn)预处理,然后O(logn)查询,其实和ST是一样的,但是好写啊

/**************************************************************
Problem: 2588
User: 96655
Language: C++
Result: Accepted
Time:4792 ms
Memory:47884 kb
****************************************************************/ #include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 1e5+;
const int INF=0x3f3f3f3f;
typedef unsigned long long ULL;
typedef long long LL;
int a[N],c[N],pos[N],n,q,cnt; int root[N],sz;
struct Node{
int l,r,v;
}o[N*]; void update(int &rt,int l,int r,int x){
o[++sz]=o[rt],rt=sz;
++o[rt].v;
if(l==r)return;
int m=(l+r)>>;
if(x<=m)update(o[rt].l,l,m,x);
else update(o[rt].r,m+,r,x);
} int d[N],fa[N][],head[N],tot;
struct Edge{
int v,next;
}edge[N<<];
void add(int u,int v){
edge[tot].v=v;
edge[tot].next=head[u];
head[u]=tot++;
}
void dfs(int u,int f){
fa[u][]=f;
d[u]=d[f]+;
update(root[u]=root[f],,cnt,pos[u]);
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].v;
if(v==f)continue;
dfs(v,u);
}
}
int lca(int u,int v){
if(d[u]<d[v])swap(u,v);
for(int t=d[u]-d[v],i=;t;t>>=,++i)
if(t&)u=fa[u][i];
if(u==v)return u;
for(int i=;i>=;--i){
if(fa[u][i]!=-&&fa[u][i]!=fa[v][i])
u=fa[u][i],v=fa[v][i];
}
return fa[u][];
}
int query(int u,int v,int k){
int k1=lca(u,v),k2=fa[k1][];
u=root[u],v=root[v],k1=root[k1],k2=root[k2];
int l=,r=cnt;
while(l!=r){
int m=(l+r)>>;
int tmp=o[o[u].l].v+o[o[v].l].v-o[o[k1].l].v-o[o[k2].l].v;
if(k<=tmp)r=m,u=o[u].l,v=o[v].l,k1=o[k1].l,k2=o[k2].l;
else l=m+,k-=tmp,u=o[u].r,v=o[v].r,k1=o[k1].r,k2=o[k2].r;
}
return a[l];
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<=n;++i)
scanf("%d",&a[i]),c[i]=a[i];
sort(a+,a+n+);
cnt=unique(a+,a++n)-a-;
for(int i=;i<=n;++i)
pos[i]=lower_bound(a+,a++cnt,c[i])-a;
tot=root[]=sz=;
memset(head,-,sizeof(head));
memset(fa,-,sizeof(fa));
for(int i=;i<n;++i){
int u,v;
scanf("%d%d",&u,&v);
add(u,v),add(v,u);
}
dfs(,);
for(int j=;(<<j)<=n;++j)
for(int i=;i<=n;++i)
if(fa[i][j-]!=-&&i!=&&j!=)
fa[i][j]=fa[fa[i][j-]][j-];
int lastans=;
while(q--){
int u,v,k;
scanf("%d%d%d",&u,&v,&k);
u^=lastans;
printf("%d",lastans=query(u,v,k));
if(q)printf("\n");
}
return ;
}

BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca的更多相关文章

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

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

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

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

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

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

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

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

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

  8. 主席树 || 可持久化线段树 || 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) ...

  9. ●BZOJ 2588 Spoj 10628. Count on a tree

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2588 题解: 主席树,在线,(求LCA)感觉主席树真的好厉害...在原树上建主席树.即对于原 ...

随机推荐

  1. Linux C 程序 函数,数组,指针,gdb调试器(SEVEN)

    函数,数组,指针,gdb调试器 1.函数定义 如果明确指定返回类型,默认为int 参数传递:实参对形参的参数传递是单向的,实参只是把自己的值赋给形参.                      形参的 ...

  2. postal.js使用

    requirejs.config({ //默认情况下模块所在目录为js/lib baseUrl: './', //当模块id前缀为app时,他便由js/app加载模块文件 //这里设置的路径是相对与b ...

  3. POJ2255二叉树

    题目大意就是给出你一个二叉树的前序和中序,要你求后序. 思路:二叉树的排序就是根据根节点的位置来定义的.所以找到二叉树的根节点是最重要的,二叉树的左子树和右子树也可以看成是二叉树,以此递归: #inc ...

  4. LAMP虚拟主机配置以及控制目录访问

    3.基于域名的虚拟主机配置 NameVirtualHost192.168.3.32:80#apache2.2.xx版本需要开启此选项,而且要和下面的保持一致:2.4.x版本就不需要此项设置了 < ...

  5. Yii表单模型使用及以数组形式提交表单数据

    按Yii文档里的描述,Yii在处理表单的一般过程是: 创建表单对应的模型类,设置字段验证规则 创建表单提交对应的action,处理提交的内容 在视图中创建表单form 在刚刚的一个小项目里,想使用aj ...

  6. linux正则表达式之-基础正则表达式(基于grep)

    linux正则表达式: 简单的说,正则表达式就是为处理大量的字符串而定义的一套规则和方法,如:假设@代表123456,!代表abcde.通过定义的这些特殊符号的铺助,系统管理员就可以快速的过滤,替换或 ...

  7. C语言中‘\n'为什么能表示CRLF两个字节

    为什么要说这个简单的问题? 众所周知,在Windows下文本文件的换行符是CRLF,占两个字节.在Unix下是LF,占一个字节.(还有奇葩的Mac是CR).但是C语言中直接printf一个 ‘\n’, ...

  8. C99标准中的部分新特性

    我有点怀疑我会不会C语言了. 1.变长数组(VLA) ; scanf("%d", &n); int arr[n]; 2.数组初始化 ] = {[] = , [] = , [ ...

  9. theano log softmax 4D

    def softmax_4d(x_4d): """ x_4d: a 4D tensor:(batch_size,channels, height, width) &quo ...

  10. 通过I2C总线向EEPROM中写入数据,记录开机次数

    没买板子之前,用protues画过电路图,实现了通过i2c总线向EEPROM中写入和读出数据. 今天,在自己买的板子上面写关于i2c总线的程序,有个地方忘了延时,调程序的时候很蛋疼.下面说说我对I2c ...