[bzoj2588][count on a tree] (主席树+lca)
Description
Input
Output
Sample Input
Sample Output
HINT
Source
Solution
普通的树上主席树
先上我的TLE树链剖分+主席树
#include<map>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 100010
#define buf 1<<21
using namespace std;
char B[buf],*p=B;
inline int Rin(){
int x=,f=;
for(;*p<''||*p>'';p++)
if(*p=='-')f=-;
for(;*p>=''&&*p<='';p++)
x=(x<<)+(x<<)+*p-'';
return x*f;
}
bool vis[N];
vector<int>d;
map<int,int>h;
int ind,n,q,ans,val[N],sz[N],rk[N],id[N],mx[N],fa[N],dep[N],top[N];
struct pt{
int v;pt *nt;
}*fst[N],mem[N<<],*e=mem;
inline void link(int x,int y){
*++e=(pt){y,fst[x]},fst[x]=e;
*++e=(pt){x,fst[y]},fst[y]=e;
}
void dfs1(int x){
rk[++ind]=x,
id[x]=ind,
vis[x]=sz[x]=;
for(pt *j=fst[x];j;j=j->nt)
if(!vis[j->v])
fa[j->v]=x,
dep[j->v]=dep[x]+,
dfs1(j->v),sz[x]+=sz[j->v],
mx[x]=sz[mx[x]]<sz[j->v]?j->v:mx[x];
}
void dfs2(int x){
vis[x]=;
top[x]=x^mx[fa[x]]?x:top[fa[x]];
if(mx[x]){
dfs2(mx[x]);
for(pt *j=fst[x];j;j=j->nt)
if(vis[j->v])dfs2(j->v);
}
}
inline int lca(int x,int y){
while(top[x]^top[y])
dep[top[x]]>dep[top[y]]?
x=fa[top[x]]:
y=fa[top[y]];
return dep[x]<dep[y]?x:y;
}
struct Seg{
Seg *l,*r;int s;
Seg(){}
Seg(Seg *_l,Seg *_r,int _s)
:l(_l),r(_r),s(_s){}
}*rt[N],*nil=new Seg(0x0,0x0,);
Seg *build(Seg *p,int s,int t,int k){
if(!(s^t))return new Seg(rt[],rt[],p->s+);
int mid=s+t>>;
return k<=mid?
new Seg(build(p->l,s,mid,k),p->r,p->s+):
new Seg(p->l,build(p->r,mid+,t,k),p->s+);
}
int secret(Seg *p1,Seg *p2,Seg *p3,Seg *p4,int s,int t,int k){
while(s<t){
int mid=s+t>>;
int c=p1->l->s+p2->l->s-p3->l->s-p4->l->s;
if(k<=c)
t=mid,
p1=p1->l,
p2=p2->l,
p3=p3->l,
p4=p4->l;
else
k-=c,
s=mid+,
p1=p1->r,
p2=p2->r,
p3=p3->r,
p4=p4->r;
}
return d[s-];
}
inline int feel(int x,int y,int k){
int t=lca(x,y);
return secret(rt[id[x]],rt[id[y]],rt[id[t]],rt[id[fa[t]]],,d.size(),k);
}
int main(){
fread(B,,buf,stdin);
n=Rin(),q=Rin();
for(int i=;i<=n;i++)
val[i]=Rin(),d.push_back(val[i]);
sort(d.begin(),d.end());
d.erase(unique(d.begin(),d.end()),d.end());
for(int i=;i<d.size();i++)
h[d[i]]=i+;
for(int i=;i<=n;i++)
val[i]=h[val[i]];
for(int i=;i<n;i++){
int x=Rin(),y=Rin();
link(x,y);
}
dfs1();dfs2();
rt[]=nil;
rt[]->l=rt[]->r=rt[];
for(int i=;i<=n;i++)
rt[i]=build(rt[id[fa[rk[i]]]],,d.size(),val[rk[i]]);
while(q--){
int x=Rin(),y=Rin(),k=Rin();
printf("%d\n",ans=feel(x^ans,y,k));
}
return ;
}
ac倍增+主席树
注意root的深度不能设为0
#include<map>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=;
inline int Rin(){
int x=,c=getchar(),f=;
for(;c<||c>;c=getchar())
if(!(c^))
f=-;
for(;c>&&c<;c=getchar())
x=(x<<)+(x<<)+c-;
return x*f;
}
bool vis[N];
pair<int,int>v[N];
int n,m,ecnt,ans,fst[N],q[N],a[N*],dep[N],fa[N][],bin[],rt[N],tot,sum[N*],ls[N*],rs[N*];
void build(int &pr,int pl,int s,int t,int k){
pr=++tot;
sum[pr]=sum[pl]+;
if(!(s^t))return;
ls[pr]=ls[pl];
rs[pr]=rs[pl];
int mid=s+t>>;
if(k<=mid)build(ls[pr],ls[pl],s,mid,k);
else build(rs[pr],rs[pl],mid+,t,k);
}
struct edge{
int v,nxt;
}e[N<<];
inline void link(int x,int y){
e[++ecnt].v=y;
e[ecnt].nxt=fst[x];
fst[x]=ecnt;
}
void bfs(){
int hd=,tl=;
vis[]=;q[]=;
while(hd^tl){
int now=q[hd++];
build(rt[now],rt[fa[now][]],,n,a[now]);
for(int j=;j<=;j++)
if(bin[j]<=dep[now])
fa[now][j]=fa[fa[now][j-]][j-];
else
break;
for(int j=fst[now];j;j=e[j].nxt)
if(!vis[e[j].v])
vis[e[j].v]=,
fa[e[j].v][]=now,
dep[e[j].v]=dep[now]+,
q[tl++]=e[j].v;
}
}
int lca(int x,int y){
if(dep[x]<dep[y])swap(x,y);
for(int j=;~j;j--)
if(dep[fa[x][j]]>=dep[y])
x=fa[x][j];
if(!(x^y))return x;
for(int j=;~j;j--)
if(fa[x][j]^fa[y][j])
x=fa[x][j],y=fa[y][j];
return fa[x][];
}
int query(int p1,int p2,int p3,int p4,int s,int t,int k){
if(!(s^t))return v[t].first;
int mid=s+t>>,c=sum[ls[p1]]+sum[ls[p2]]-sum[ls[p3]]-sum[ls[p4]];
if(k<=c)return query(ls[p1],ls[p2],ls[p3],ls[p4],s,mid,k);
return query(rs[p1],rs[p2],rs[p3],rs[p4],mid+,t,k-c);
}
int req(int x,int y,int k){
int t=lca(x,y);
return query(rt[x],rt[y],rt[t],rt[fa[t][]],,n,k);
}
int main(){
for(int i=;i<=;i++)
bin[i]=<<i;
n=Rin(),m=Rin();
for(int i=;i<=n;i++)
v[i].first=Rin(),v[i].second=i;
sort(v+,v++n);
for(int i=;i<=n;i++)
a[v[i].second]=i;
for(int i=;i<n;i++){
int x=Rin(),y=Rin();
link(x,y);link(y,x);
}
dep[]=;bfs();
for(int i=;i<=m;i++)
{
int x,y,k;
scanf("%d%d%d",&x,&y,&k);
printf("%d",ans=req(x^ans,y,k));
if(i!=m)puts("");
}
return ;
}
可持久化线段树注意事项
1.对于较大的数据范围,用动态开点线段树时注意直接l+r>>1会爆,可以用l+r>>1=(l>>1)+(r>>1)+(l&r&1)
2.对于lca问题,根节点的深度统一设为1
3.树剖是O(2n)的,可能会超时,用倍增+宽搜可能稍稍快一些
4.我认为指针这种东西最好少用,处理不好可能RE
[bzoj2588][count on a tree] (主席树+lca)的更多相关文章
- 洛谷P2633/bzoj2588 Count on a tree (主席树)
洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...
- 【BZOJ2588】Spoj 10628. Count on a tree 主席树+LCA
[BZOJ2588]Spoj 10628. Count on a tree Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lasta ...
- SPOJ Count on a tree(主席树+LCA)
一.题目 COT - Count on a tree You are given a tree with N nodes. The tree nodes are numbered from 1 to ...
- BZOJ 2588: Spoj 10628. Count on a tree 主席树+lca
分析:树上第k小,然后我想说的是主席树并不局限于线性表 详细分析请看http://www.cnblogs.com/rausen/p/4006116.html,讲的很好, 然后因为这个熟悉了主席树,真是 ...
- BZOJ2588:Count on a tree(主席树)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- spoj COT - Count on a tree(主席树 +lca,树上第K大)
您将获得一个包含N个节点的树.树节点的编号从1到Ñ.每个节点都有一个整数权重. 我们会要求您执行以下操作: uvk:询问从节点u到节点v的路径上的第k个最小权重 输入 在第一行中有两个整数Ñ和中号.( ...
- 【BZOJ-2588】Count on a tree 主席树 + 倍增
2588: Spoj 10628. Count on a tree Time Limit: 12 Sec Memory Limit: 128 MBSubmit: 3749 Solved: 873[ ...
- 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】Count on a tree 主席树
这题给人开了个新思路. 原本构造一个序列的主席树,是这个位置用上个位置的信息来省空间,树上的主席树是继承父亲的信息来省空间. 此题若带修改怎么办? 若对某个点的权值做修改,则这个点的子树都会受影响,想 ...
随机推荐
- c#官方推荐md5通用加密类
/// <summary> /// MD5加密 /// </summary> /// <param name="input">需要加密的字符串& ...
- 基于 getter 和 setter 撸一个简易的MVVM
Angular 和 Vue 在对Angular的学习中,了解到AngularJS 的两个主要缺点: 对于每一次界面时间,Ajax 或者 timeout,都会进行一个脏检查,而每一次脏检查又会在内部循环 ...
- c 进程间的通信
在上篇讲解了如何创建和调用进程 c 进程和系统调用 这篇文章就专门讲讲进程通信的问题 先来看一段下边的代码,这段代码的作用是根据关键字调用一个Python程序来检索RSS源,然后打开那个URL #in ...
- Linux上oracle精简版客户端快速部署
RHEL6 + Oracle 11g客户端快速部署 需求:只是用到客户端的sqlplus, sqlldr功能. 方案:用精简版实现客户端的快速部署 1.上传oracle精简版客户端到服务器/tmp目录 ...
- 基于HTML5的WebGL应用内存泄露分析
上篇(http://www.hightopo.com/blog/194.html)我们通过定制了CPU和内存展示界面,体验了HT for Web通过定义矢量实现图形绘制与业务数据的代码解耦及绑定联动, ...
- [Tool] 插入折叠区域功能
之前写了一个 仿博客园网页端推荐的插入代码插件, 后来在总结一些技术文档时,总是想把一些属性或者方法,参数等,都用表格的形式清晰的列举出来,但是插入的表格太大的话,上下跨度就显得特别大,来回上下滚动的 ...
- 了解java注解
类似于下面这样的就是注解 注解可以在类上,成员变量上,方法上等 假如有2个注解是这样的:(其中的Author和Date) 那么这2个注解的定义就是这样的: Author注解: Date注解: 可以看到 ...
- HTML5笔记1——HTML5的发展史及标签的改变
记得第一次接触HTML5还是在<联信永益>实习那会儿(2011),当时一个项目技术选型的时候面临两种选择,分别是Silverlight和HTML5,那是用的最新的IE浏览器版本还是IE9, ...
- Canvas的width,height 和 样式中Canvas的width,height
控制Canvas的大小,有两种方式: 1:直接设置Canvas标签上的书width,height属性值; 2:通过Css设置Canvas的width,height; 这两种方式,区别是很大的. 1:C ...
- 纯css3圆形从中心向四周扩散动画效果
查看效果:http://hovertree.com/texiao/css3/37/ 先来个简单的示例,例如: @keyframes hovertreemove{from {top:30px;}to { ...