CSU 2172 买一送一

2024-04-05 20:48
文章标签 csu 2172 买一送一

本文主要是介绍CSU 2172 买一送一,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:点击打开链接

题意:略。

题解:首先要看出来这是一棵树,然后就想怎么去重

设当前节点为u,商品类型为a[u],父节点为fa

在dfs的过程中维护这几个信息:

1、 上一个以a[u]为第二分量的二元对的数目pre[a[u]]

2、 从根到fa的不同商品类型的数目num,即以当前a[u]为第二分量的二元对的数目

3、 从根到fa的答案ans[fa]

那么当前的答案就是ans[u]=ans[fa]+num-pre[a[u]]

时间复杂度O(n)。

注意会爆int,要使用long long!

代码:

#include<bits/stdc++.h>
using namespace std;
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define pb push_back
const int N = 1e5+10;int n,a[N],ct[N],hs[N],cnt;
long long ans[N];///注意使用long long 极端情况1e5*1e5
vector<int> e[N],v[N];void dfs(int fa) {for(int i=0;i<e[fa].size();i++) {int x=e[fa][i];if(!hs[a[fa]]) cnt++;hs[a[fa]]++;ans[x]=ans[fa]+cnt-ct[a[x]];v[a[x]].pb(cnt);ct[a[x]]=cnt;dfs(x);hs[a[fa]]--;if(hs[a[fa]]==0) cnt--;v[a[x]].pop_back();ct[a[x]]=v[a[x]][v[a[x]].size()-1];}
}int main() {while(scanf("%d",&n)!=EOF) {int x;rep(i,2,n) scanf("%d",&x),e[x].pb(i);rep(i,1,n) scanf("%d",&a[i]);///初始化 prerep(i,1,n) v[i].pb(0);///到n就行了 防止mle 和 tledfs(1);rep(i,2,n) printf("%lld\n",ans[i]);rep(i,1,n) e[i].clear(),v[i].clear();mst(ct,0),mst(hs,0),cnt=0;}return 0;
}

 

这篇关于CSU 2172 买一送一的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/878109

相关文章

csu(背包的变形题)

题目链接 这是一道背包的变形题目。好题呀 题意:给n个怪物,m个人,每个人的魔法消耗和魔法伤害不同,求打死所有怪物所需的魔法 #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>//#include<u>#include<map

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

CSU - 1556 Jerry's trouble(快速幂取模)

【题目链接】:click here 【题目大意】:计算x1^m+x2^m+..xn^m(1<=x1<=n)( 1 <= n < 1 000 000, 1 <= m < 1000) 【解题思路】:快速幂取模 代码: solution one: #include<bits/stdc++.h>#define LL long longusing namespace std;const

[CSU - 1811 (湖南省赛16)] Tree Intersection (dfs序维护子树+离线询问+树状数组)

CSU - 1811 (湖南省赛16) 给定一棵树,每个节点都有一个颜色 问割掉任意一条边,生成的两个子树中颜色集合的交集大小 这个是 dfs序处理子树 + 离线询问 + bit维护 的解法 首先问题转化为求解一个子树中有多少种颜色以及独有颜色的数量 用总的颜色数量减去独有颜色数量即为这棵子树的答案 先做一遍 dfs,再按 dfs序重新组建颜色序列 这样对子树的询问,就变成

[CSU - 1811 (湖南省赛16)] Tree Intersection (启发式合并)

CSU - 1811 (湖南省赛16) 给定一棵树,每个节点都有一个颜色 问割掉任意一条边,生成的两个子树中颜色集合的交集大小 问题可以转化为任意一棵子树中, 这个子树中的颜色数量和只在这个子树中出现的颜色的数量 用总的颜色数量减去独有颜色数量即为这棵子树的答案 从 lcy大爷那里学到了机智的启发式合并的做法 对每个点维护一个 map 来记录这个点为根的子树中颜色的及其数

csu 1541: There is No Alternative(最小生成树 Kruskal)

题目链接:点击打开链接 题意就是 求出图中最小生成树的必要边的个数以及这些边权值的和 首先用Kruskal求出最小生成树的值 保存最小生成树中的边 然后枚举每条边  如果这条边是在刚才最小生成树中的边 则把它删除再求最小生成树的值 与之前的进行比较 如果值大了  则这条边是必须的  保存这条边的值 #include<cstdio>#include<cstdlib>#incl

csu 1526: Beam me out!(强连通分量 Tarjan)

从1开始的所有路径 是否都能到达n 所用的步数是否是无限的 1)判断n是否可达 2)判断是否有环 3)判断是否所有的点都可以从1开始可达 #include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <string.h>#includ

CSU 1623 Inspectors(二分图最大权匹配 KM算法)(UVAlive 6879)

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1623 选用一些边 覆盖所有的点 使得这些边的权值和最小 比赛时的想法是用一般图最大权匹配 样例也过了 但是提交总是WA 看kuangbin模版中写的是点的个数必须是偶数。。是不是有可能是这个原因 改用二分图最大权匹配之后就过了。。。。 #include <cstdio>

csu 1601 War(并查集)

1601: War Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 82   Solved: 24 [ Submit][ Status][ Web Board] Description AME decided to destroy CH’s country. In CH’ country, There are N vill

CSU 文本计算器

文本计算器 Time Limit: 1 Sec   Memory Limit: 128 MB Submit: 37   Solved: 12 [ Submit][ Status][ Web Board] Description Bob讨厌复杂的数学运算.看到练习册上的算术题,Bob很是头痛.为了完成作业,Bob想要你帮忙写一个文本版的四则运算计算器.这个计算器的功能需