HDU 5266 pog loves szh III
题目:pog loves szh III
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5266
题意:给一棵树,有m个询问,每个询问问所有下标在[l, r]之中的结点的最近公共祖先。
思路:
线段树 + LCA
这道题数据有点大,n、m均在30万,所以有点卡内存,做这道题才知道自己平时做题有多浪费内存。。。
题目提示小心栈溢出,我AC以后再用普通的dfs试,发现不会出现该问题,但最好还是自己写栈,用while代替递归。
题目思路并不难,线段树处理区间,建树时使用lca在线计算即可。
AC代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 #include<math.h> 5 #include<set> 6 #include<map> 7 #include<list> 8 #include<stack> 9 #include<queue> 10 #include<vector> 11 #include<string> 12 #include<iostream> 13 #include<algorithm> 14 using namespace std; 15 #define lson rt<<1 16 #define rson rt<<1|1 17 #define N 300005 18 #define M 300005 19 #define Mod 1000000007 20 #define LL long long 21 #define INF 0x7fffffff 22 vector<int> e[M]; 23 int xu[N*2],xo,pos[M],h[M]; 24 25 struct SSS 26 { 27 int rt,fa; 28 int i; 29 }; 30 31 void dfs(int rt,int fa,int ceng) //普通递归 32 { 33 h[rt]=ceng; 34 for(int i=0;i<e[rt].size();i++) 35 { 36 if(e[rt][i]!=fa) dfs(e[rt][i],rt,ceng+1); 37 pos[rt]=xo; 38 xu[xo++]=rt; 39 } 40 } 41 42 SSS st[M]; 43 void dfs(int rt) //while型递归 44 { 45 int top=0; 46 st[top].rt=rt; 47 st[top].fa=-1; 48 st[top].i=0; 49 h[rt]=1; 50 top++; 51 while(top) 52 { 53 SSS a=st[top-1]; 54 st[top-1].i++; 55 if(a.i<e[a.rt].size()) 56 { 57 int ad=e[a.rt][a.i]; 58 if(ad!=a.fa) 59 { 60 h[ad]=h[a.rt]+1; 61 st[top].rt=ad; 62 st[top].fa=a.rt; 63 st[top++].i=0; 64 } 65 if(a.i!=0) xu[xo++]=a.rt; 66 } 67 else 68 { 69 pos[a.rt]=xo; 70 xu[xo++]=a.rt; 71 top--; 72 } 73 } 74 } 75 int f[N<<1][24]; 76 void rmq() 77 { 78 for(int j=0;j<xo;j++) f[j][0]=xu[j]; 79 for(int i=1;i<24;i++) 80 { 81 for(int j=0;j<xo;j++) 82 { 83 if(j+(1<<i)-1 < xo) 84 { 85 if(h[f[j][i-1]]<h[f[j+(1<<i-1)][i-1]]) 86 { 87 f[j][i]=f[j][i-1]; 88 } 89 else 90 { 91 f[j][i]=f[j+(1<<i-1)][i-1]; 92 } 93 } 94 } 95 } 96 } 97 int look(int l,int r) 98 { 99 if(l>r) l^=r^=l^=r; 100 int k=(int)log2((double)(r-l+1)); 101 if(h[f[l][k]]<h[f[r-(1<<k)+1][k]]) return f[l][k]; 102 else return f[r-(1<<k)+1][k]; 103 } 104 105 int v[M<<2]; 106 void build(int l,int r,int rt) 107 { 108 if(l==r) 109 { 110 v[rt]=l; 111 return ; 112 } 113 build(l,(l+r)/2,rt<<1); 114 build((l+r)/2+1,r,rt<<1|1); 115 v[rt] = look(pos[v[rt<<1]],pos[v[rt<<1|1]]); 116 } 117 int query(int ll,int rr,int l,int r,int rt) 118 { 119 if(l==ll&&r==rr) return v[rt]; 120 int mid=(ll+rr)/2; 121 if(l>mid) return query(mid+1,rr,l,r,rt<<1|1); 122 else if(r<=mid) return query(ll,mid,l,r,rt<<1); 123 else return look(pos[query(ll,mid,l,mid,rt<<1)],pos[query(mid+1,rr,mid+1,r,rt<<1|1)]); 124 } 125 int main() 126 { 127 int x,y,n,m; 128 while(scanf("%d",&n)!=EOF) 129 { 130 for(int i=1;i<=n;i++) 131 { 132 e[i].clear(); 133 h[i]=INF; 134 } 135 for(int i=1;i<n;i++) 136 { 137 scanf("%d%d",&x,&y); 138 e[x].push_back(y); 139 e[y].push_back(x); 140 } 141 xo=0; 142 dfs(1,-1,1); 143 rmq(); 144 build(1,n,1); 145 scanf("%d",&m); 146 while(m--) 147 { 148 scanf("%d%d",&x,&y); 149 printf("%d\n",query(1,n,x,y,1)); 150 } 151 } 152 return 0; 153 }