题面
https://www.luogu.org/problem/P5290
题解
真的是我傻逼,十二省联考$day2$至今还是我的噩梦。$day1$起码一直在调可持久化$trie$树,$day2$真的是一道题都不会写啊。
皮配以为是生成函数,写了$20pts$暴力就放掉了。
春节十二响读错题意,想了半天没有想出来,甚至一条链的情况本来想出来排序的方法了,但是过了一会竟然忘掉了(可能是因为太紧张吧,脑子里面奇奇怪怪的不知道在想什么,可能在想我的女神吧),最后写了一个不知所云的线段树,我明明都看出来$T2$是最简单的一题了,但最后还是没做出来,唉。
最后对着希望看了一个半小时,放弃了。
回家之后重新想这道题,只需要对每一棵子树分别做,把一条链的情况拓展出来就可以了。窝写的$set$启发式合并。
现在想想,要是再遇到一样的绝望,我该怎么办呢?
#include <cstdio> #include <iostream> #include<cstring> #include<vector> #include<algorithm> #include<set> #define ri register int #define N 200050 using namespace std; int n,a[N]; vector<int> son[N]; int fa[N],fs[N]; multiset<int,greater<int>> s[N]; multiset<int,greater<int>>::iterator it1,it2; void solve(int x) { if (son[x].size()==0) { fs[x]=x; s[x].insert(a[x]); return; } int maxs=0,yson=-1; for (ri i=0;i<son[x].size();i++) { solve(son[x][i]); if (s[fs[son[x][i]]].size()>maxs) maxs=s[fs[son[x][i]]].size(),yson=son[x][i]; } fs[x]=fs[yson]; int now=fs[x]; for (ri i=0;i<son[x].size();i++) if (son[x][i] != yson) { for (it1=s[fs[son[x][i]]].begin(),it2=s[now].begin();it1!=s[fs[son[x][i]]].end();it1++,it2++) { if (*it1>*it2) s[now].erase(it2),s[now].insert(*it1); } } s[now].insert(a[x]); return; } int main() { scanf("%d", &n); for (ri i=1;i<=n;i++) scanf("%d", &a[i]); for (ri i=2;i<=n;i++) { scanf("%d",&fa[i]); son[fa[i]].push_back(i); } solve(1); long long ans=0; for (it1=s[fs[1]].begin();it1!=s[fs[1]].end();it1++) { ans+=*it1; } cout<<ans<<endl; }