给出一个n个结点的二叉树的前序和中序遍历,初始权值为0,有如下3个操作分别
1 x val
2 x val
3 x
分别代表 x的子树的权值都加val包括x。
根到x上的结点都减val包括x。
输出层次x的结点权值总和。不存在该层的话输出-1。
输入格式:
第一行一个n,第二行和第三行分别是前序和中序遍历,接下来为m个操作。1≤n≤30,−100≤val≤100
输出格式:
对于询问3的输出结果。
输入样例:
3
2 1 3
1 2 3
3
1 2 1
2 1 10
3 1
输出样例:
-9
分析:
二叉树的一些基本操作…
先序/后序+中序建树,DFS与BFS。
以下代码:
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int INF=0x3f3f3f3f;
int v[50],Left[50],Right[50];
int n,m;
int root,op,x,val;
int pre[50],mid[50],layer[50];
int build(int prel,int prer,int midl,int midr)
{ //先序遍历+中序遍历 建立二叉树
if(prel>prer)
return -1;
int k,root=pre[prel];
for(k=midl;k<=midr;k++)
{
if(mid[k]==root)
break;
}
int Ln=k-midl;
Left[root]=build(prel+1,prel+Ln,midl,k-1);
Right[root]=build(prel+Ln+1,prer,k+1,midr);
return root;
}
void BFS(int i) //利用BFS获取各结点所在层数
{
queue<int> q;
layer[i]=1;
q.push(i);
while(!q.empty())
{
int t=q.front();
q.pop();
if(Left[t]!=-1)
{
layer[Left[t]]=layer[t]+1;
q.push(Left[t]);
}
if(Right[t]!=-1)
{
layer[Right[t]]=layer[t]+1;
q.push(Right[t]);
}
}
}
void op1_DFS(int i) //利用DFS实现操作1
{
if(i==-1)
return;
v[i]+=val;
op1_DFS(Left[i]);
op1_DFS(Right[i]);
}
int op2_DFS(int i) //利用DFS实现操作2
{
if(i==x)
{
v[i]-=val;
return (-1)*val;
}
else if(i==-1)
return 0;
else
{
int L=op2_DFS(Left[i]),R=op2_DFS(Right[i]);
v[i]+=L+R;
return L+R;
}
}
int op3() //操作3
{
int ans=0;
bool flag=false;
for(int i=1;i<=n;i++)
{
if(layer[i]==x)
{
flag=true;
ans+=v[i];
}
}
if(flag)
printf("%d\n",ans);
else
printf("-1\n");
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&pre[i]);
for(int i=1;i<=n;i++)
scanf("%d",&mid[i]);
root=build(1,n,1,n);
memset(v,0,sizeof(v));
BFS(root);
scanf("%d",&m);
while(m--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d %d",&x,&val);
op1_DFS(x);
}
else if(op==2)
{
scanf("%d %d",&x,&val);
op2_DFS(root);
}
else
{
scanf("%d",&x);
op3();
}
}
return 0;
}