【每日一题】 点权和

点权和

https://ac.nowcoder.com/acm/problem/14393

点权和

解题思路:我们统计每个结点的时候,需要考虑自己本身的贡献、自己父亲的贡献以及自己儿子的贡献
1.自己的贡献:由自己操作的次数和父亲操作的次数和儿子操作的次数构成
2.父亲的贡献:由自己操作的次数和父亲操作的次数和父亲的父亲操作的次数
3.儿子的贡献:由自己的操作次数*孩子的个数和他儿子+1的次数和他孙子+1的次数构成
接下来就是如何进行上述的求解
我们可以用三个数组分别表示自己的操作次数、自己的儿子操作的次数、自己的孙子操作的次数(a[x],b[x],c[x])
每次操作都要使a[x]++,同时再使得b[fa[x]]++,同时使得c[fa[fa[x]]]++

#include<bits/stdc++.h>
using namespace std;
const int mode=19260817;
const int maxn=1e5+10;
long long sonsize[maxn],a[maxn],b[maxn],c[maxn],fa[maxn];
int main()
{
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=2;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		fa[i]=x;
		sonsize[x]++;
	}
	long long ans=0;
	for(int i=1;i<=m;i++)
	{
		int x;
		scanf("%d",&x);
		a[x]++;
		if(fa[x]!=0) b[fa[x]]++;
		if(fa[fa[x]]!=0) c[fa[fa[x]]]++;
		long long f1=(a[fa[x]]+b[fa[x]]+a[fa[fa[x]]])%mode;
		long long f2=(a[x]+a[fa[x]]+b[x])%mode;
		long long f3=(sonsize[x]*a[x]%mode+b[x]+c[x])%mode;
		long long res=(f1+f2+f3)%mode;
		ans=(ans+i*res%mode)%mode;
	}
	printf("%lld\n",ans);
	return 0;
} 


全部评论

相关推荐

10-30 19:23
已编辑
山东大学(威海) C++
牛至超人:我了个雷 1.实习经历写太长了吧,精简一点,你写那么老多,面试官看着都烦 2.项目经历你放俩竞赛干啥单独拿出来写上几等奖就行了呗 3.一大雷点就是项目经历里的那个课程设计,大家都知道课程设计巨水,不要写课程设计,换一个名字,就叫学生管理系统,面试官问就说是自己做的项目,不要提课程设计的事 4.那个交流经历,简化一下塞到最上面的教育经历里就行了 5.简历尽量一页纸
点赞 评论 收藏
分享
09-22 22:22
中山大学 Java
乌鱼子萨奇:羡慕你啊,直接转正了,都不用经历秋招的炼狱,但是你少经历了很多痛苦的事情啊
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务