BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
分析:树上第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的更多相关文章
- 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 ...
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- 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 + 主席树 )
Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...
- 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个节点的树,每个点 ...
- 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
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2588 题解: 主席树,在线,(求LCA)感觉主席树真的好厉害...在原树上建主席树.即对于原 ...
随机推荐
- 链表C++模板实现
#include <iostream.h> #include <stdlib.h> //结点模板类 template <typename t1, typename t2& ...
- Photoshop快捷键
ctrl+del :铺后景色alt+del:铺前景色ctrl+d:取消选框ctrl+t:拉伸(挡住文字)TAB:显示(隐藏)工具栏ctrl+alt+i:反选ctrl+r:辅佐线ctrl+j:复制并添加 ...
- java basic
//java 声明常量 //final 数据类型 常量名=值; //as: final float PI=3.14f;/ PI=3.14002F //默认浮点为 double //break:跳出多重 ...
- Nodejs初学者福音
Nodejs+Express+MongoDb 搭建个人博客 001 我喜欢把任务或者工作分解成工作流来完成,如下,后面将会按照流程来详述,希望能为Nodejs初学者及推广Nodejs做出些努力. n ...
- Python调试工具-Spyder
OS:Windows 7 关键字:Python IDE, Spyder 1.安装工具pip:https://pip.pypa.io/en/latest/installing.html 下载 get-p ...
- Monitor All SQL Queries in MySQL (alias mysql profiler)
video from youtube: http://www.youtube.com/watch?v=79NWqv3aPRI one blog post: Monitor All SQL Querie ...
- Python之添加新元素
现在,班里有3名同学: >>> L = ['Adam', 'Lisa', 'Bart'] 今天,班里转来一名新同学 Paul,如何把新同学添加到现有的 list 中呢? 第一个办法是 ...
- pywinauto如何获取gridwindow控件的屏幕位置
一:问题描述 问题一:通过查找pywinauto在线文档,其中没有讲解到gridwindow控件的方法,我不知道这个控件是不是标准控件,还是pywinauto根本就没适配这个控件.从网上查询了好多资料 ...
- xcode 中添加pch文件
xcode6以后去掉了pch文件,据说苹果是觉得把头文件加在pch中,会让编译变慢,但是作为我们程序员来说难不倒我们,所以我们手动来添加一下pch文件即可 首先创建一个工程,然后创建一个pch文件 ...
- c# 获取MP3和AMR文件格式的时长
//网上摘录整理private long GetAMRFileDuration(string fileName) { ; FileStream fs = new FileStream(fileName ...