http://acm.hdu.edu.cn/showproblem.php?pid=4409
由G2 <= G1 +1得 题目给的是一个DFS序列 然后单调栈找出每个节点的父节点 然后三种操作都很裸
有个坑点 题目中uv的lca不能等于uv 题目说的很隐晦 可以通过下面这句话猜一下
"Since Mr. X has no ancestor in the list, so it's guaranteed that there is no question asking about Mr. X's ancestor. "
#include <bits/stdc++.h>
using namespace std;
struct node1
{
int fa;
int dep;
string s;
};
struct node2
{
int id;
int dep;
};
map <string,int> mp;
stack <node2> stk;
vector <int> edge[30010];
node1 pre[30010];
int dp[30010][20];
int deep[30010];
int n,q;
bool cmp(int u,int v)//?
{
return pre[u].s<pre[v].s;
}
void init()
{
node2 tmp;
int i;
while(!stk.empty()) stk.pop();
for(i=2;i<=n;i++)
{
while(!stk.empty()&&stk.top().dep>=pre[i].dep) stk.pop();
if(stk.empty()) pre[i].fa=1;
else pre[i].fa=stk.top().id;
tmp.id=i,tmp.dep=pre[i].dep;
stk.push(tmp);
}
for(i=1;i<=n;i++) edge[i].clear();
for(i=2;i<=n;i++)
{
edge[pre[i].fa].push_back(i);
edge[i].push_back(pre[i].fa);
}
for(i=1;i<=n;i++) sort(edge[i].begin(),edge[i].end(),cmp);
}
void dfs(int cur,int fa)
{
int i,v;
//for(i=first[cur];i!=-1;i=edge[i].next)
for(i=0;i<edge[cur].size();i++)
{
v=edge[cur][i];
if(v!=fa)
{
dp[v][0]=cur;
deep[v]=deep[cur]+1;
dfs(v,cur);
}
}
}
void solve()
{
int i,j;
dp[1][0]=0;
deep[1]=0;
dfs(1,0);
for(j=1;(1<<j)<=n;j++)
{
for(i=1;i<=n;i++)
{
dp[i][j]=dp[dp[i][j-1]][j-1];
}
}
}
int getlca(int u,int v)
{
int i;
if(deep[u]<deep[v]) swap(u,v);
for(i=log2(n);i>=0;i--)
{
if(deep[dp[u][i]]>=deep[v])
{
u=dp[u][i];
}
}
if(u==v) return u;
for(i=log2(n);i>=0;i--)
{
if(dp[u][i]!=dp[v][i])
{
u=dp[u][i];
v=dp[v][i];
}
}
return dp[u][0];
}
void show(int cur)
{
int i,v;
for(i=0;i<pre[cur].dep;i++) printf(".");
cout<<pre[cur].s<<endl;
for(i=0;i<edge[cur].size();i++)
{
v=edge[cur][i];
if(v!=pre[cur].fa) show(v);
}
}
int main()
{
string tmp,su,sv;
int i,j,k,len,u,v,lca;
char op[10];
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
mp.clear();
cin>>pre[1].s;
mp[pre[1].s]=1;
pre[1].dep=0;
for(i=2;i<=n;i++)
{
cin>>tmp;
len=tmp.size();
pre[i].dep=0;
for(j=0;j<len&&tmp[j]=='.';j++) pre[i].dep++;
pre[i].s.resize(len-pre[i].dep);
for(k=0;k<len-pre[i].dep;j++,k++) pre[i].s[k]=tmp[j];
mp[pre[i].s]=i;
}
//for(i=1;i<=n;i++) cout<<pre[i].dep<<" "<<pre[i].s<<endl;
init();
solve();
scanf("%d",&q);
while(q--)
{
scanf("%s",op);
if(op[0]=='L') show(1);
else if(op[0]=='b')
{
cin>>su;
u=mp[su];
if(u==1) printf("%d\n",1);
else if(pre[u].fa!=1) printf("%d\n",edge[pre[u].fa].size()-1);
else printf("%d\n",edge[pre[u].fa].size());
}
else
{
cin>>su>>sv;
u=mp[su],v=mp[sv];
lca=getlca(u,v);
//cout<<pre[lca].s<<endl;
if(u==lca||v==lca) cout<<pre[pre[lca].fa].s<<endl;
else cout<<pre[lca].s<<endl;
}
}
}
return 0;
}