HDU 5266 pog loves szh III (선분 수 + 온라인 LCA 회전 RMQ)

제목 주소: HDU 5266 문 제 는 RMQ 를 돌려 LCA 를 구 하 는 방법 으로 매우 간단 합 니 다. l - r 구간 내 dfs 순서 가 가장 크 고 가장 작은 것 만 찾 으 면 됩 니 다. 그러면 선분 트 리 나 RMQ 로 구간 의 최 치 를 유지 하면 됩 니 다.그리고 dfs 서 의 가장 큰 점 과 dfs 서 의 가장 작은 점 을 찾 은 최근 공공 조상 입 니 다.코드 는 다음 과 같 습 니 다:
#include <iostream>
#include <string.h>
#include <math.h>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <map>
#include <set>
#include <stdio.h>
using namespace std;
#define LL __int64
#define pi acos(-1.0)
#define root 1, n, 1
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1
#pragma comment(linker, "/STACK:1024000000")
const int mod=1e4+7;
const int INF=0x3f3f3f3f;
const double eqs=1e-9;
const int MAXN=300000+10;
int fir[MAXN], F[MAXN<<1], tot, deg[MAXN], rmq[MAXN<<1];
int head[MAXN], cnt, n;
int dp[MAXN<<1][30];
int Max[MAXN<<2], Min[MAXN<<2], q_max, q_min;
struct node
{
        int u, v, next;
}edge[MAXN<<1];
void add(int u, int v)
{
        edge[cnt].v=v;
        edge[cnt].next=head[u];
        head[u]=cnt++;
}
void init()
{
        memset(head,-1,sizeof(head));
        cnt=tot=0;
}
void dfs(int u, int dep, int fa)
{
        F[++tot]=u;
        rmq[tot]=dep;
        fir[u]=tot;
        for(int i=head[u];i!=-1;i=edge[i].next){
                int v=edge[i].v;
                if(v==fa) continue ;
                dfs(v,dep+1,u);
                F[++tot]=u;
                rmq[tot]=dep;
        }
}
struct ST
{
        int i, j;
        void init()
        {
                for(i=1;i<=tot;i++) dp[i][0]=i;
                for(j=1;(1<<j)<=tot;j++){
                        for(i=1;i<=tot-(1<<j)+1;i++){
                                dp[i][j]=rmq[dp[i][j-1]]<rmq[dp[i+(1<<j-1)][j-1]]?dp[i][j-1]:dp[i+(1<<j-1)][j-1];
                        }
                }
        }
        int Query(int l, int r)
        {
                if(r<l) swap(l,r);
                int k=0;
                while((1<<k+1)<=r-l+1) k++;
                return rmq[dp[l][k]]<rmq[dp[r+1-(1<<k)][k]]?dp[l][k]:dp[r+1-(1<<k)][k];
        }
}st;
void PushUp(int rt)
{
        Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
        Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);
}
void Build(int l, int r, int rt)
{
        if(l==r){
                Max[rt]=Min[rt]=fir[l];
                return ;
        }
        int mid=l+r>>1;
        Build(lson);
        Build(rson);
        PushUp(rt);
}
void Query(int ll, int rr, int l, int r, int rt)
{
        if(ll<=l&&rr>=r){
                q_max=max(q_max,Max[rt]);
                q_min=min(q_min,Min[rt]);
                return ;
        }
        int mid=l+r>>1;
        if(ll<=mid) Query(ll,rr,lson);
        if(rr>mid) Query(ll,rr,rson);
}
int main()
{
        int q, u, v, l, r, i;
        while(scanf("%d",&n)!=EOF){
                init();
                for(i=1;i<n;i++){
                        scanf("%d%d",&u,&v);
                        add(u,v);
                        add(v,u);
                }
                dfs(1,0,-1);
                st.init();
                Build(root);
                scanf("%d",&q);
                while(q--){
                        scanf("%d%d",&u,&v);
                        if(u>v) swap(u,v);
                        q_min=INF;
                        q_max=0;
                        Query(u,v,root);
                        //printf("%d %d
"
,q_min,q_max); printf("%d
"
,F[st.Query(q_min,q_max)]); } } return 0; }

좋은 웹페이지 즐겨찾기