首页 > 代码库 > [HDU5266]pog loves szh III

[HDU5266]pog loves szh III

首先dfs,记录每个点第一次被访问到的时间

那么区间LCA其实就是访问最早和访问最晚的点的LCA

找时间最早和最晚用ST表,找LCA用倍增

 

 1 #include<stdio.h>
 2 #include<string.h>
 3 int n,tot,dfsclk,h[300010],nex[600010],to[600010],dfsnum[300010],dfsid[300010],dep[300010],fa[300010][20],stmin[300010][20],stmax[300010][20],log2[300010];
 4 void add(int a,int b){
 5     tot++;
 6     nex[tot]=h[a];
 7     to[tot]=b;
 8     h[a]=tot;
 9 }
10 void dfs(int x,int f,int d){
11     fa[x][0]=f;
12     dep[x]=d;
13     dfsclk++;
14     dfsnum[x]=dfsclk;
15     dfsid[dfsclk]=x;
16     for(int i=h[x];i;i=nex[i]){
17         if(to[i]!=f)dfs(to[i],x,d+1);
18     }
19 }
20 int max(int a,int b){return a>b?a:b;}
21 int min(int a,int b){return a<b?a:b;}
22 void swap(int&a,int&b){
23     int t=a;
24     a=b;
25     b=t;
26 }
27 int lca(int x,int y){
28     if(dep[x]<dep[y])swap(x,y);
29     int i;
30     for(i=19;i>=0;i--){
31         if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
32     }
33     if(x==y)return x;
34     for(i=19;i>=0;i--){
35         if(fa[x][i]!=fa[y][i]){
36             x=fa[x][i];
37             y=fa[y][i];
38         }
39     }
40     return fa[x][0];
41 }
42 int querymax(int l,int r){
43     int k=log2[r-l];
44     return max(stmax[l][k],stmax[r-(1<<k)+1][k]);
45 }
46 int querymin(int l,int r){
47     int k=log2[r-l];
48     return min(stmin[l][k],stmin[r-(1<<k)+1][k]);
49 }
50 int main(){
51     int q,i,j,a,b;
52     while(~scanf("%d",&n)){
53         tot=0;
54         memset(h,0,sizeof(h));
55         for(i=1;i<n;i++){
56             scanf("%d%d",&a,&b);
57             add(a,b);
58             add(b,a);
59         }
60         dfsclk=0;
61         dfs(1,0,1);
62         
63         log2[0]=0;
64         for(i=1;i<=n;i++){
65             stmin[i][0]=stmax[i][0]=dfsnum[i];
66             log2[i]=log2[i-1];
67             if((1<<log2[i])<=(i>>1))log2[i]++;
68         }
69         for(j=1;j<20;j++){
70             for(i=1;i<=n;i++)fa[i][j]=fa[fa[i][j-1]][j-1];
71         }
72         for(j=1;j<20;j++){
73             for(i=1;i+(1<<(j-1))<=n;i++){
74                 stmax[i][j]=max(stmax[i][j-1],stmax[i+(1<<(j-1))][j-1]);
75                 stmin[i][j]=min(stmin[i][j-1],stmin[i+(1<<(j-1))][j-1]);
76             }
77         }
78         scanf("%d",&q);
79         while(q--){
80             scanf("%d%d",&a,&b);
81             printf("%d\n",lca(dfsid[querymin(a,b)],dfsid[querymax(a,b)]));
82         }
83     }
84 }

 

[HDU5266]pog loves szh III