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
  2 #include<string.h>
  3 #include
  4 #include
  5 #include<set>
  6 #include
  7 #include
  8 #include
  9 #include
 10 #include
 11 #include<string>
 12 #include
 13 #include
 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)
 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;j0]=xu[j];
 79   for(int i=1;i<24;i++)
 80   {
 81     for(int j=0;j)
 82     {
 83       if(j+(1<1 < xo)
 84       {
 85         if(h[f[j][i-1]]1<1)][i-1]])
 86         {
 87           f[j][i]=f[j][i-1];
 88         }
 89         else
 90         {
 91           f[j][i]=f[j+(1<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]]1<1][k]]) return f[l][k];
102   else return f[r-(1<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)
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 }