题意:
给予一颗树,最开始点权为0,每次将与一个点x树上距离<=1的所有点点权+1,之后询问这些点修改后的点权和(与点x树上距离<=1的所有点点权之和).如果是第i次操作,这次操作结果为ans,则这个结果的值加上
i * ans,结果模19260817。

思路:
设数组f1[]记录该点本身修改的次数,数组f2[]记录该点儿子的修改次数,数组f3[]记录该点孙子的修改次数。
该点v的点权= f1[v] (本身修改次数) + f1[parent[v]] (父亲修改次数) +f2[v] (儿子修改次数)
该点父亲的点权=f1[parent[v]] (父亲修改次数) + f1[parent[parent[v]]] (爷爷修改次数) + f2[parent[v]] (父亲儿子的修改次数)
该点儿子的点权和=f1[v] * child[v] (本身修改次数*儿子个数) + f2[v] (儿子的修改次数) + f3[v] (孙子修改的次数)

代码:

#include <bits/stdc++.h>
#define inf 19260817
using namespace std;

typedef long long ll;

inline int read()
{
    int x=0,f=1;
    char c=getchar();
    while(c<'0'||c>'9')
    {
        if(c=='-')
        {
            f=-f;
        }
        c=getchar();
    }
    while(c>='0'&&c<='9')
    {
        x=(x<<1)+(x<<3)+(c^48);
        c=getchar();
    }
    return f*x;
}

int parent[100005];
int child[100005];
ll sum[100005], f1[100005], f2[100005], f3[100005];

void fun(int v,int k)
{
    f1[v]++;
    if(v!=1)
    f2[parent[v]]++;
    if(parent[v]!=1)
    f3[parent[parent[v]]]++;
}

ll result(int v)
{
    ll z=(f1[v]+f1[parent[v]]+f2[v])%inf;
    z=(z+f1[parent[v]]+f1[parent[parent[v]]]+f2[parent[v]])%inf;
    z=(z+f1[v]*child[v]%inf+f2[v]+f3[v])%inf;
    return z;
}

int main()
{
    int n, m;
    n=read();
    m=read();
    for(int i=2; i<=n; i++)
    {
        int v;
        v=read();
        parent[i]=v;
        child[v]++;
    }
    ll ans=0;
    for(int i=1; i<=m; i++)
    {
        int v;
        v=read();
        fun(v,0);
        ll z=result(v);
        ans=(ans+(z*i)%inf)%inf;
    }
    cout << ans << endl;
    return 0;
}