输入样例:
5
2 4 1 3 0
8
2 is the root
1 and 4 are siblings
3 and 0 are on the same level
2 is the parent of 4
3 is the left child of 4
1 is the right child of 2
4 and 0 are on the same level
100 is the right child of 3
输出样例:
Yes
Yes
Yes
Yes
Yes
No
No
No
题解 : 写的代码极丑。
先离散化,建树的时候储存下来这个节点对应到数组上的下标,a[id[i]]=x,i是x的映射。上次有一个题目也是这样的查询,但是那个是通过每次把所有的点for循环直至a[i]=x,找到对应的数组下标,时间复杂度较高。
下面的代码是错误的,最后一个测试点MLE。
#include<cstdio>
#include<map>
using namespace std;
const int N=100+5,M=N*N*1000,INF=0x3f3f3f3f;
map<int,int>refl;
int root,k[N],a[M],id[N],tot,vis[M];
void insert_(int x,int h,int pos)
{
if(!vis[pos])
{
vis[pos]=1;
a[pos]=x;
if(!refl[x])
refl[x]=++tot;
id[tot]=pos;
k[tot]=h;
return;
}
if(x<a[pos])
insert_(x,h+1,pos<<1);
else
insert_(x,h+1,pos<<1|1);
k[pos]=h;
}
int main()
{
tot=0;
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
insert_(x,1,1);
}
int m;scanf("%d",&m);
while(m--)
{
int x,y,tmp;char s[15];
scanf("%d%s",&x,s);
tmp=x,x=refl[x];
if(s[0]=='a')
{
scanf("%d",&y);
scanf("%s",s),scanf("%s",s);
y=refl[y];
if(s[0]=='s')//siblings
{
if(!x||!y||x==y||id[x]==1||id[y]==1)
{puts("No");continue;}
puts(a[id[x]>>1]==a[id[y]>>1]?"Yes":"No");
}
else//the same level
{
scanf("%s",s),scanf("%s",s),scanf("%s",s);
if(!x||!y)
{puts("No");continue;}
puts(k[x]==k[y]?"Yes":"No");
}
}
else
{
scanf("%s",s),scanf("%s",s);
if(s[0]=='r'&&s[1]=='o')//root
{
if(!x)
{puts("No");continue;}
puts(tmp==a[1]?"Yes":"No");
continue;
}
if(s[0]=='l')//left child
{
scanf("%s",s),scanf("%s%d",s,&y);
if(!refl[y]||!x||id[x]==1)
{puts("No");continue;}
puts((!(id[x]&1)&&a[id[x]>>1]==y)?"Yes":"No");
}
if(s[0]=='r')//right child
{
scanf("%s",s),scanf("%s%d",s,&y);
if(!refl[y]||!x||id[x]==1)
{puts("No");continue;}
puts(((id[x]&1)&&a[id[x]>>1]==y)?"Yes":"No");
}
if(s[0]=='p')//parent
{
scanf("%s%d",s,&y);
y=refl[y];
if(!y||!x||id[y]==1)
{puts("No");continue;}
puts(tmp==a[id[y]>>1]?"Yes":"No");
}
}
}
}