给一棵树,q次询问,每次询问给连续的一个闭区间,问区间所有数的LCA是多少。
做一个dfs序,其中把dfs序最小的点和最大的点做一次LCA求出的点就是答案。
#include <bits/stdc++.h> #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define up rt,rt<<1,rt<<1|1 using namespace std; const int M = 3e5+7; int n,q; int tot,cnt,head[M]; struct edge { int v,next; }e[M<<1]; void init(){ tot=cnt=0;memset(head,-1,sizeof(head)); } void add(int u,int v){ e[++cnt].v=v;e[cnt].next=head[u]; head[u]=cnt; } int f[M][22],deep[M],in[M]; void dfs(int u,int fa,int d){//dfs(1,-1,0) deep[u]=d; in[u]=++tot; for(int i=head[u];~i;i=e[i].next){ int v=e[i].v; if(v==fa) continue; dfs(v,u,d+1); f[v][0]=u; } return ; } void work(){//RMQ for(int i=1;i<20;i++) for(int j=1;j<=n;j++) f[j][i]=f[f[j][i-1]][i-1]; } int lca(int x,int y){//lca if(deep[x]<deep[y]) swap(x,y); int dt=deep[x]-deep[y]; for(int i=0;i<20;i++) if(dt&(1<<i)) 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]; } struct Seg { int mx,mn,mxpos,mnpos; }seg[M<<2]; void pushup(int rt,int l,int r){ if(seg[l].mx>seg[r].mx){ seg[rt].mx=seg[l].mx;seg[rt].mxpos=seg[l].mxpos; } else{ seg[rt].mx=seg[r].mx;seg[rt].mxpos=seg[r].mxpos; } if(seg[l].mn<seg[r].mn){ seg[rt].mn=seg[l].mn;seg[rt].mnpos=seg[l].mnpos; } else{ seg[rt].mn=seg[r].mn;seg[rt].mnpos=seg[r].mnpos; } } void build(int l,int r,int rt){ if(l==r){ seg[rt].mx=seg[rt].mn=in[l]; seg[rt].mxpos=seg[rt].mnpos=l; return ; } int mid=(l+r)>>1; build(lson); build(rson); pushup(up); } int query(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R){ return rt; } int mid=(l+r)>>1,res=-1; if(L<=mid){ res=query(L,R,lson); } if(R>mid){ int tmp=query(L,R,rson); if(seg[res].mx<seg[tmp].mx||res==-1) res=tmp; } return res; } int querymn(int L,int R,int l,int r,int rt){ if(L<=l&&r<=R){ return rt; } int mid=(l+r)>>1,res=-1; if(L<=mid){ res=querymn(L,R,lson); } if(R>mid){ int tmp=querymn(L,R,rson); if(seg[res].mn>seg[tmp].mn||res==-1) res=tmp; } return res; } int main(){ //freopen("1.in","r",stdin); //freopen("1.out","w",stdout); while(~scanf("%d",&n)){ init(); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); add(u,v);add(v,u); } dfs(1,-1,0); work(); build(1,n,1); scanf("%d",&q); int u,v; while(q--){ scanf("%d%d",&u,&v);if(u>v) swap(u,v); int mx=seg[query(u,v,1,n,1)].mxpos,mn=seg[querymn(u,v,1,n,1)].mnpos; printf("%d\n",lca(mx,mn)); } } return 0; }