[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 主席树
这题给人开了个新思路. 原本构造一个序列的主席树,是这个位置用上个位置的信息来省空间,树上的主席树是继承父亲的信息来省空间. 此题若带修改怎么办? 若对某个点的权值做修改,则这个点的子树都会受影响,想 ...
随机推荐
- Oracle使用SQL传输表空间
源环境:RHEL 6.4 + Oracle 11.2.0.4 目的环境:RHEL 6.4 + Oracle 11.2.0.4 DG双机 要求:使用SQL传输表空间DBS_D_JINGYU从源环境到目的 ...
- 基于WebGL 的3D呈现A* Search Algorithm
http://www.hightopo.com/demo/astar/astar.html 最近搞个游戏遇到最短路径的常规游戏问题,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现 ...
- Docker 基础 : 数据管理
用户在使用 Docker 的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份,甚至多个容器之间进行数据的共享,这必然涉及容器的数据管理操作.容器中管理数据主要有两种方式:数据 ...
- java设计模式之简单工厂模式
简单工厂: 简单工厂的优点: 1.去除客户端与具体产品的耦合,在客户端与具体的产品中增加一个工厂类,增加客户端与工厂类的耦合 2.封装工厂类,实现代码平台的复用性,创建对象的过程被封装成工厂类,可以多 ...
- Spark 入门
Spark 入门 目录 一. 1. 2. 3. 二. 三. 1. 2. 3. (1) (2) (3) 4. 5. 四. 1. 2. 3. 4. 5. 五. Spark Shell使用 ...
- C#开机自动启动程序代码
新建一个winform拖一个checkbox进来.. 然后设置它的changed事件. 已经测试过,可以直接复制使用. private void checkBox1_CheckedChanged(ob ...
- Delphi_03_Delphi_Object_Pascal_基本语法_01
这次是一个基本语法的第一部分,包括变量.变量初始化.常量.运算符.字符串等内容. { 本程序演示 Delphi Pascal 的基本语法 1.变量及变量的初始化 2.常量 3.运算符 3. 4. } ...
- JVM之内存结构
JVM是按照运行时数据的存储结构来划分内存结构的.JVM在运行Java程序时,将他们划分成不同格式的数据,分别存储在不同的区域,这些数据就是运行时数据.运行时数据区域包括堆,方法区,运行时常量池,程序 ...
- spring源码:IOC(li)
一.BeanDefinition BeanDefinition是配置文件<bean>元素标签在容器中内部表示形式.创建最终的BeanDefinition主要包括两个步骤: 1)利用Bean ...
- 每次新建项目出现appcompat_v7 解决方法
ADT升级版本后每次新建项目出现appcompat_v7 , 解决方案如下 问题生成: