Count on a tree bzoj-2588 Spoj-10628

题目大意:给定一棵n个点的树,m次查询。查询路径上k小值。

注释:$1\le n,m\le 10^5$。

想法:好像更博顺序有一些问题... ...

root[i]表示以i为根的主席树根

对于查询的两个点x,y,我们只需要查询

root[x]+root[y]-root[lca(x,y)]-root[fa[lca(x,y)]]的主席树即可。

具体地,每个节点的权值线段树维护的是当前结点到根的路径上这些点权值的权值线段树。

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
int ans,tot,cnt,anc,n,m,q,x,y,z,d[100010],v[100010],h[100010],l[3000010],r[3000010],to[200010],head[100010],next[200010],sum[3000010],root[100010],f[100010][20];
map<int,int>b;
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
int lca(int x,int y)
{
if(d[x]<d[y])
{
swap(x,y);
}
int dep=d[x]-d[y];
for(int i=0;i<=19;i++)
{
if((dep&(1<<i))!=0)
{
x=f[x][i];
}
}
if(x==y)
{
return x;
}
for(int i=19;i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int updata(int pre,int L,int R,int k)
{
int mid=(L+R)>>1;
int rt=++cnt;
l[rt]=l[pre];
r[rt]=r[pre];
sum[rt]=sum[pre]+1;
if(L==R)
{
return rt;
}
else
{
if(k<=mid)
{
l[rt]=updata(l[pre],L,mid,k);
}
else
{
r[rt]=updata(r[pre],mid+1,R,k);
}
}
return rt;
}
int query(int x,int y,int anc,int fa,int L,int R,int k)
{
int mid=(L+R)>>1;
if(L==R)
{
return b[L];
}
int num=sum[l[x]]+sum[l[y]]-sum[l[anc]]-sum[l[fa]];
if(num>=k)
{
return query(l[x],l[y],l[anc],l[fa],L,mid,k);
}
else
{
return query(r[x],r[y],r[anc],r[fa],mid+1,R,k-num);
}
}
void dfs(int x,int fa)
{
d[x]=d[fa]+1;
int k=lower_bound(h+1,h+1+m,v[x])-h;
b[k]=v[x];
root[x]=updata(root[fa],1,n,k);
for(int i=1;i<=19;i++)
{
f[x][i]=f[f[x][i-1]][i-1];
}
for(int i=head[x];i;i=next[i])
{
if(to[i]!=fa)
{
f[to[i]][0]=x;
dfs(to[i],x);
}
}
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
{
scanf("%d",&v[i]);
h[i]=v[i];
}
sort(h+1,h+1+n);
m=unique(h+1,h+1+n)-h-1;
for(int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(1,0);
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&x,&y,&z);
x=x^ans;
anc=lca(x,y);
ans=query(root[x],root[y],root[anc],root[f[anc][0]],1,n,z);
printf("%d\n",ans);
}
}

小结:在树上的主席树就是nb... ...

[bzoj2588][Spoj10628]Count on a tree_主席树的更多相关文章

  1. 【BZOJ-2588】Count on a tree 主席树 + 倍增

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 3749  Solved: 873[ ...

  2. 【bzoj2588】Count on a tree 主席树

    这题给人开了个新思路. 原本构造一个序列的主席树,是这个位置用上个位置的信息来省空间,树上的主席树是继承父亲的信息来省空间. 此题若带修改怎么办? 若对某个点的权值做修改,则这个点的子树都会受影响,想 ...

  3. BZOJ2588 SPOJ10628 Count on a tree 【主席树】

    BZOJ2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中l ...

  4. 洛谷P2633/bzoj2588 Count on a tree (主席树)

    洛谷P2633/bzoj2588 Count on a tree 题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K ...

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

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

  6. [bzoj2588][count on a tree] (主席树+lca)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  7. BZOJ2588:Count on a tree(主席树)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  8. 洛谷P2633 Count on a tree(主席树上树)

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

  9. P2633 Count on a tree(主席树)

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

随机推荐

  1. zzulioj--1730--通信基站(全排列+dfs)(好题)

    1730: 通信基站 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 28  Solved: 11 SubmitStatusWeb Board Desc ...

  2. [NOIP 2014] 寻找道路

    [题目链接] http://uoj.ac/problem/19 [算法] 首先,在反向图上从终点广搜,求出每个点是否可以在答案路径中 然后在正向图中求出源点至终点的最短路,同样可以使用广搜 时间复杂度 ...

  3. category中添加属性的简单方式

    一.概念扩充: 1.如我们所知,使用category是用来对现有类进行功能扩展,或者将类分成多模块的一种方式.由声明和实现两部分组成.可以单独写成Objiective-C File类型文件(包含.h和 ...

  4. Gym - 101981K The 2018 ICPC Asia Nanjing Regional Contest K.Kangaroo Puzzle 暴力或随机

    题面 题意:给你1个20*20的格子图,有的是障碍有的是怪,你可以每次指定上下左右的方向,然后所有怪都会向那个方向走, 如果2个怪撞上了,就融合在一起,让你给不超过5w步,让所有怪都融合 题解:我们可 ...

  5. go之数组

    一.数组概念 go语言提供了数组类型的数据结构 数组是具有 [唯一类型] 的一组 [固定长度] 的数据项序列,这种类型可以是任意类型 二.数组声明 var variable_name [SIZE]va ...

  6. vmware 14黑屏处理办法

    从12升级到了14,但是发现所有的虚拟机都不能用了,黑屏.挂起的时候反而会显示界面,但是继续运行就是黑屏. 记录下解决办法. 修复LSP 以管理员身份运行CMD命令: netsh winsock re ...

  7. elasticsearch性能调优

    转载 http://www.cnblogs.com/hseagle/p/6015245.html 该es调优版本可能有低,但是思想主体不变,不合适的参数可以自己找最新的版本相应的替代,或者增删 ela ...

  8. Centos7.5 在桌面创建AndroidStudio快捷方式

    Centos7 在桌面创建AndroidStudio快捷方式 前言 最近安装了Centos7,打算将开发平台转移到Linux下,安装好AndroidStudio后,桌面没有快捷方式有些不习惯,随自己创 ...

  9. HttpWebRequest 知识点

    string Url = System.Configuration.ConfigurationManager.AppSettings["CallPaperInvoiceURL"]; ...

  10. VMWare虚拟机Centos 6.9中的 linux 配置静态ip地址上外网

    1.查看网络 # ifconfig 发现网络还没有配置,ping不通 2.修改网卡配置文件 # vim /etc/sysconfig/network-scripts/ifcfg-eth0 添加如下配置 ...