学习了树转数组,然后就是一个裸的线段树,或许是数据问题,在线算法比#1067 快了不少
#include<iostream>
#include<map>
#include<string.h>
#include<algorithm>
#include<fstream>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
using namespace std;
#define lch(i) ((i)<<1)
#define rch(i) ((i)<<1|1)
#define sqr(i) ((i)*(i))
#define pii pair<int,int>
#define mp make_pair
#define FOR(i,b,e) for(int i=b;i<=e;i++)
#define FORE(i,b,e) for(int i=b;i>=e;i--)
#define ms(a) memset(a,0,sizeof(a))
const int maxnum =200005;
const int mod = 1000000007;
int n,m,len,deepest;
struct node
{
char* name;
int pans;
int depth;
vector<node*> son;
node(): name(NULL),
depth(0),
son(),
pans(0){}
node(char *str): depth(0),
son(),
pans(0){
name = new char[strlen(str)];
strcpy(name,str);
}
~node(){
if(name)
delete[] name;
}
};
node* root;
map<string,node*> name2node;
node* ans[maxnum*2];int num=0;
struct tnode
{
int l,r;
node* minn;
int gmin(){
return (l+r)>>1;
}
}tree[maxnum*2];
void dfs(node* rt,int dep){
rt->depth=dep;
ans[++num]=rt;
int si = rt->son.size();
FOR(i,0,si-1){
dfs(rt->son[i],dep+1);
ans[++num]=rt;
}
rt->pans = num;
}
void Btree(int rt,int l,int r){
tree[rt].l=l;
tree[rt].r=r;
tree[rt].minn = ans[l];
if(l==r)return;
int mid = tree[rt].gmin();
Btree(lch(rt),l,mid);
Btree(rch(rt),mid+1,r);
tree[rt].minn=tree[lch(rt)].minn;
if(tree[rch(rt)].minn->depth<tree[lch(rt)].minn->depth)
tree[rt].minn=tree[rch(rt)].minn;
return;
}
node* Stree(int rt,int l,int r){
if(l==tree[rt].l&&tree[rt].r==r){
return tree[rt].minn;
}
int mid = tree[rt].gmin();
if(l>mid)
return Stree(rch(rt),l,r);
else if(r<=mid)
return Stree(lch(rt),l,r);
node* tmp1 =Stree(lch(rt),l,mid);
node* tmp2 = Stree(rch(rt),mid+1,r);
return tmp1->depth<tmp2->depth?tmp1:tmp2;
}
int main()
{
/*fstream fin("G:/1.txt");
fin>>n;*/
cin>>n;
char name[1000];
root=0;
node *far,*son;
FOR(i,1,n){
scanf("%s",name);
/*fin>>name;*/
if(name2node[name]==0){
far = new node(name);
name2node[name]=far;
}
else far = name2node[name];
if(root==0)
root = far;
scanf("%s",name);
/*fin>>name;*/
if(name2node[name]==0){
son = new node(name);
name2node[name]=son;
}else
far = name2node[name];
far->son.push_back(son);
}
dfs(root,0);
Btree(1,1,num);
cin>>m;
/*fin>>m;*/
int st,en;
FOR(i,1,m){
scanf("%s",name);
/* fin>>name;*/
far = name2node[name];
scanf("%s",name);
/*fin>>name;*/
son = name2node[name];
st = far->pans;
en = son->pans;
if(st>en) swap(st,en);
printf("%s\n",Stree(1,st,en)->name);
}
return 0;
}