SSL P2387 树

目录:

题目:

树 题目

题意:

给出原始权值,以及每个点的节点,然后在1操作时进行对奇数节点+val,对偶数节点-val,在2操作时输出当前询问节点的权值

分析:

这道题最大的阻碍就是对每个节点的后续操作,我们可以用lazy数组来保存,在1操作时直接加上,而2操作时可以用一个递归来进行求解,在代码中小编会更为详细的讲解
而对于输入,直接保存节点是行不通的,我们可以转换思路,保存他们的父节点,这样无形间还方便了我们的递归

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#define LL long long
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}
int n,m,xx,yy,w[100001],lazy[100001],ques,ls[100001],father[100001],ans;
char c;
int updata(int k,int mov)
{
    if (!k) return 0;//没有父节点,结束
    //mov用来区分当前是要加还是要减
    return updata(father[k],-mov)+lazy[k]*mov;//父节点的权值+自己的权值
}
int main()
{
    n=read();m=read();
    for (int i=1;i<=n;i++)
    {
        w[i]=read();
    }
    for (int i=1;i<n;i++)
    {
        xx=read();yy=read();
        father[yy]=xx;
    }
    for (int i=1;i<=m;i++)
    {
        ques=read();
        if (ques==2)
        {
            xx=read();
            printf("%d\n",w[xx]+updata(xx,1));
        }
        else
        {
            xx=read();yy=read();
            lazy[xx]+=yy;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35786326/article/details/79898630