[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 主席树
这题给人开了个新思路. 原本构造一个序列的主席树,是这个位置用上个位置的信息来省空间,树上的主席树是继承父亲的信息来省空间. 此题若带修改怎么办? 若对某个点的权值做修改,则这个点的子树都会受影响,想 ...
随机推荐
- 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查
Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...
- .NET文件并发与RabbitMQ(初探RabbitMQ)
本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...
- 五步掌握OOM框架AutoMapper基本使用
本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文地址 www.cnblogs.com/tdws 写在前面 OOM顾名思义,Object-Object-Mapping实体间相互转换,Aut ...
- Hibernate-模板模式
在我的博客<Hibernate总结(一)>在对数据库的增删改查前后重复的使用了得到Session与关闭Session等操作,因此我想到了模板设计模式. 模板设计模式概述: 定义一个操作中的 ...
- 在网站开发中很有用的8个 jQuery 效果【附源码】
jQuery 作为最优秀 JavaScript 库之一,改变了很多人编写 JavaScript 的方式.它简化了 HTML 文档遍历,事件处理,动画和 Ajax 交互,而且有成千上万的成熟 jQuer ...
- AngularJS下对数组的比较
Javascript不能直接用==或者===来判断两个数组是否相等,无论是相等还是全等都不行,以下两行JS代码都会返回false <script type="text/javascri ...
- asp.net将图片转成二进制存入数据库
一.代码如下 int code = int.Parse(this.TextBox1.Text);//图片编码 string value = this.FileUpload1.PostedFile.Fi ...
- android Service介绍
一.简介 android中service(服务)运行于后台,没有界面.和其他组件一样,service也运行在主线程中,因此不能用它来做耗时的请求或者动作.可以在服务中开启线程,在线程中做耗时操作.可以 ...
- Android 手机卫士--平移动画实现
本文实现如下几个界面之间的平移动画实现 本文地址:http://www.cnblogs.com/wuyudong/p/5954847.html,转载请注明出处. 分析: 导航界面移动过程中,平移动画 ...
- iOS网络1——NSURLConnection使用详解
原文在此 一.整体介绍 NSURLConnection是苹果提供的原生网络访问类,但是苹果很快会将其废弃,且由NSURLSession(iOS7以后)来替代.目前使用最广泛的第三方网络框架AFNetw ...