题目大意:

  给定一棵n个点的树,每个点有一个权值,m个询问,每次询问树上点x到点y的路径上的第k小数。

思路:

  dfs后给每个节点一个dfs序,以每个点在他父亲的基础上建立主席树,询问时用(点x+点y-点lca(x,y)-点dad[lca(x,y)])即可得到x到y的链,在上面查询即可。

代码:

 #include<cstdio>
#include<iostream>
#include<algorithm>
#define N 200009
using namespace std; int tot=,dfn,num,cnt,pa[N][],to[N],next[N],head[N],lc[N*],rc[N*],deep[N],sum[N*],id[N],pos[N],root[N],a[N],b[N]; int read()
{
int x=,y=;char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') y=-;ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-;ch=getchar();}
return x*y;
} void add(int x,int y)
{
to[++cnt]=y,next[cnt]=head[x],head[x]=cnt;
} void dfs(int x)
{
int i;id[x]=++dfn,pos[dfn]=x;
for (i=;i<=;i++)
if ((<<i)<=deep[x]) pa[x][i]=pa[pa[x][i-]][i-];
else break;
for (i=head[x];i;i=next[i])
if (pa[x][]!=to[i])
{
deep[to[i]]=deep[x]+;
pa[to[i]][]=x;
dfs(to[i]);
}
} void change(int l,int r,int x,int &cur,int _cur)
{
cur=++num;
lc[cur]=lc[_cur];
rc[cur]=rc[_cur];
sum[cur]=sum[_cur]+;
if (l==r) return;
int mid=l+r>>;
if (x<=b[mid]) change(l,mid,x,lc[cur],lc[_cur]);
else change(mid+,r,x,rc[cur],rc[_cur]);
} int LCA(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
int i,t=deep[x]-deep[y];
for (i=;i<=;i++)
if ((<<i)&t) x=pa[x][i];
for (i=;i>=;i--)
if (pa[x][i]!=pa[y][i]) x=pa[x][i],y=pa[y][i];
if (x==y) return x;
return pa[x][];
} int ask(int x,int y,int k)
{
int a=root[id[x]],b=root[id[y]],c=LCA(x,y),d=pa[c][],l=,r=tot;
c=root[id[c]],d=root[id[d]];
while (l<r)
{
int t=sum[lc[a]]+sum[lc[b]]-sum[lc[c]]-sum[lc[d]],mid=l+r>>;
if (t>=k) a=lc[a],b=lc[b],c=lc[c],d=lc[d],r=mid;
else a=rc[a],b=rc[b],c=rc[c],d=rc[d],l=mid+,k-=t;
}
return l;
} int main()
{
int n=read(),m=read(),i,x,y,ans=,k;
for (i=;i<=n;i++) a[i]=read(),b[i]=a[i];
for (i=;i<n;i++) x=read(),y=read(),add(x,y),add(y,x);
dfs(),sort(b+,b+n+);
for (i=;i<=n;i++)
if (b[tot]!=b[i]) b[++tot]=b[i];
for(i=;i<=n;i++) change(,tot,a[pos[i]],root[i],root[id[pa[pos[i]][]]]);
for (i=;i<=m;i++)
{
x=read(),y=read(),k=read(),x^=ans;
printf("%d",ans=b[ask(x,y,k)]);
if (i<m) printf("\n");
}
return ;
}

Spoj 10628. Count on a tree 题解的更多相关文章

  1. 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 ...

  2. 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 ...

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

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

  4. 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 ...

  5. 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 ...

  6. BZOJ 2588: Spoj 10628. Count on a tree( LCA + 主席树 )

    Orz..跑得还挺快的#10 自从会树链剖分后LCA就没写过倍增了... 这道题用可持久化线段树..点x的线段树表示ROOT到x的这条路径上的权值线段树 ----------------------- ...

  7. 2588: Spoj 10628. Count on a tree

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5766  Solved: 1374 ...

  8. 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个节点的树,每个点 ...

  9. 主席树 || 可持久化线段树 || 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) ...

随机推荐

  1. EF – 4.CRUD与事务

    5.6.1 <Entity Framework数据更新概述>  首先介绍Entity Framework实现CRUD的基本方法,接着介绍了如何使用分部类增强和调整数据实体类的功能与行为特性 ...

  2. jQuery – 6.选择器

    1. 属性过滤选择器: 1. $("div[id]")选取有id属性的<div> 2. $("div[title=test]")选取title属性为 ...

  3. 【Java环境变量的配置问题】

    首先是JVM.JRE.JDK三者之间的关系: java的跨平台性依赖于Java虚拟机:jvm(Java Virtual Machine),而jre(Java Runtime Environment,中 ...

  4. OCJP(1Z0-851) 模拟题分析(九)over

    Exam : 1Z0-851 Java Standard Edition 6 Programmer Certified Professional Exam 以下分析全都是我自己分析或者参考网上的,定有 ...

  5. 使用PHP获取时间今天 明天 昨天 时间戳的详解

    使用php获取时间今天明天昨天时间戳 2013-06-20 11:12 <?php echo "今天:".date("Y-m-d")."< ...

  6. hdu 4278 2012天津赛区网络赛 数学 *

    8进制转为10进制 #include<cstdio> #include<iostream> #include<algorithm> #include<cstr ...

  7. 用计算器计算“异或CRC”

    再计算器上输入以下数字,每输入一个数字,按一下“Xor”

  8. jbox使用总结

    jbox是一个不错的插件 当使用get打开新页面的时候,可以使用h.对像ID来获得对像ID的值 Js代码 js代码: /** * @description: test * @author: BrinP ...

  9. hdu 4281(MTSP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4281 题意:给出N个点,第一个点是裁判,其他N-1个点需要裁判过去回答问题,每个点需要的时间不一样,而 ...

  10. AndroidStudio导入新项目一直卡在Building gradle project info的解决解决方案

      尝试了各种办法,FQ,离线gradle等,发现一个更好用更简单的办法: 解决方案: 1.随便找一个你能运行的as项目 2.打开gradle-wrapper.properties,文件目录:项目/g ...