题解:P8968 觅光 | Searching for Hope (hard ver.)

题目传送门

简要复述 easy ver. 带给我们的信息(因为这是 hard ver.,所以不提供详细证明):一个关键的结论是我们应当投入相同电荷的小球,这样对方选择的机会最小,显然是对我们有利的。记 i 的答案为 ansi,初始 ansisi,然后每一层的另一个节点 y 带来的贡献有 ansiansi+min(ansi,sy)

所以每次只有两个操作 ×2 或加 sy。显然 ×2 的总操作次数是 O(nlogV) 次的,可以暴力乘,剩下的打 tag。又有 ansi<szy<ansj,则 2ansi<ansj+szy,所以操作后子树内的元素相对顺序是不变的。

具体来说每个节点维护一个小根堆,设一个节点的两个子节点为 x,ysx>sy)。子树 y 都是 ×2 直接暴力,子树 x 中将 >sy 的找出来 ×2,注意这里不能直接 pop,观察到这些数组成一个包含根的连通块,直接暴力从根往下遍历就好了,时间复杂度 O(nlogV+nlogn)

Code:

const int N = 1e6 + 10; int n, rt[N], ls[N], rs[N], dst[N], ch[N][2], fa[N], st[N], nd[N]; long long val[N], laz[N], s[N]; inline void pd(const int &x){ if(laz[x]) val[ls[x]] += laz[x], val[rs[x]] += laz[x], laz[ls[x]] += laz[x], laz[rs[x]] += laz[x], laz[x] = 0; } inline int merge(int x, int y){ if(!x || !y) return x | y; if(val[x] > val[y]) swap(x, y); pd(x); rs[x] = merge(rs[x], y); if(dst[rs[x]] > dst[ls[x]]) swap(ls[x], rs[x]); dst[x] = dst[rs[x]] + 1; return x; } int main(){ ios::sync_with_stdio(0); cin.tie(0); cin >> n; for(int i = 2; i <= n; i++){ cin >> fa[i]; if(ch[fa[i]][0]) ch[fa[i]][1] = i; else ch[fa[i]][0] = i; } for(int i = 1; i <= n; i++) cin >> s[i]; for(int i = n; i; i--){ if(fa[i]) s[fa[i]] += s[i]; val[i] = s[i]; if(s[ch[i][0]] < s[ch[i][1]]) swap(ch[i][0], ch[i][1]); if(!ch[i][1]) rt[i] = merge(i, rt[ch[i][0]]); else{ st[st[0] = 1] = rt[ch[i][1]]; while(st[0]){ int x = st[st[0]--]; val[x] *= 2; pd(x); if(ls[x]) st[++st[0]] = ls[x]; if(rs[x]) st[++st[0]] = rs[x]; } if(rt[ch[i][0]]) st[st[0] = 1] = rt[ch[i][0]]; nd[nd[0] = 1] = i; while(st[0]){ int x = st[st[0]--]; if(val[x] < s[ch[i][1]]){ nd[++nd[0]] = x, val[x] = (val[x] << 1) - s[ch[i][1]]; pd(x); if(ls[x]) st[++st[0]] = ls[x]; if(rs[x]) st[++st[0]] = rs[x]; } } val[rt[ch[i][0]]] += s[ch[i][1]], laz[rt[ch[i][0]]] += s[ch[i][1]]; rt[i] = merge(merge(rt[ch[i][1]], i), rt[ch[i][0]]); } } st[st[0] = 1] = rt[1]; while(st[0]){ int x = st[st[0]--]; pd(x); if(ls[x]) st[++st[0]] = ls[x]; if(rs[x]) st[++st[0]] = rs[x]; } for(int i = 1; i <= n; i++) cout << val[i] << " "; }

__EOF__

本文作者louisliang
本文链接https://www.cnblogs.com/louisliang/p/18668259.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   louisliang  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示