【spoj】【COT - Count on a tree】【可持久化线段树】

来源:互联网 发布:四维星装饰选材软件 编辑:程序博客网 时间:2024/05/21 10:46

题目大意

给出一棵树,询问两点路径上第k大点权是什么。

解题思路

自上到下建可持久化线段树,维护当前点到根的信息,使用权值线段树记录size,查询的时候两端的值减去lca和lca的父亲的值即当前路径的权值线段树,即可求解。

code

#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#define LF double#define LL long long#define Min(a,b) ((a<b)?a:b)#define Max(a,b) ((a>b)?a:b)#define Fo(i,j,k) for(int i=j;i<=k;i++)#define Fd(i,j,k) for(int i=j;i>=k;i--)using namespace std;int const MxN=1e5+100,MxA=2147483647;int N,M,Edge,Node,Mx,A[MxN+9],Begin[MxN+9],Dep[MxN+9],Fa[MxN+9][25],To[MxN*2+9],Next[MxN*2+9],Size[MxN*40+9],Son[MxN*40+9][2];void Insert(int U,int V){    To[++Edge]=V;    Next[Edge]=Begin[U];    Begin[U]=Edge;}void Oper(int Pre,int Now,int L,int R,int V){    int Mid=(1ll*L+R)>>1,P=(V<=Mid)?0:1;    Size[Now]=Size[Pre]+1;    if(L==R)return;    Son[Now][!P]=Son[Pre][!P];    Son[Now][P]=++Node;    if(P)L=Mid+1;else R=Mid;    Oper(Son[Pre][P],Son[Now][P],L,R,V);}void Dfs(int Now,int Pre){    Dep[Now]=Dep[Pre]+1;    Oper(Pre,Now,1,MxA,A[Now]);    for(int i=Begin[Now];i;i=Next[i])if(To[i]!=Pre)Fa[To[i]][0]=Now,Dfs(To[i],Now);}int Lc(int U,int V){    if(Dep[U]<Dep[V])swap(U,V);    Fd(i,Mx,0)if(Dep[Fa[U][i]]>=Dep[V])U=Fa[U][i];    if(U==V)return U;    Fd(i,Mx,0)if(Fa[U][i]!=Fa[V][i])U=Fa[U][i],V=Fa[V][i];    return Fa[U][0];}int Qury(int U,int V,int Lca,int FaLca,int L,int R,int K){    int Mid=(1ll*L+R)>>1,Tmp,P=((Tmp=Size[Son[U][0]]+Size[Son[V][0]]-Size[Son[Lca][0]]-Size[Son[FaLca][0]])>=K)?0:1;    if(L==R)return L;    if(P)L=Mid+1,K-=Tmp;else R=Mid;    return Qury(Son[U][P],Son[V][P],Son[Lca][P],Son[FaLca][P],L,R,K);}int main(){    //freopen("d.in","r",stdin);    //freopen("d.out","w",stdout);    scanf("%d%d",&N,&M);Node=N;    Fo(i,1,N)scanf("%d",&A[i]);    int U,V;    Fo(i,2,N){        scanf("%d%d",&U,&V);        Insert(U,V);Insert(V,U);    }    Dfs(1,0);int K,Lca;Mx=log(N)/log(2);    Fo(j,1,Mx)Fo(i,1,N)Fa[i][j]=Fa[Fa[i][j-1]][j-1];    Fo(i,1,M){        scanf("%d%d%d",&U,&V,&K);Lca=Lc(U,V);        printf("%d\n",Qury(U,V,Lca,Fa[Lca][0],1,MxA,K));    }    return 0;}
0 0
原创粉丝点击