小塔正在一张有向但定连通的图上玩游戏。这张图包含n个点,第i个点的权值为a,当小美从i移动到 Nexti时,游戏规则如下:
如果aNeati>ai,小美的金币将增加x;
如果aNexti≤ai,小美的金币将增加y。
小塔会提出q次询问,每个询问从某个点u出发,移动不超过k步,最多能获得多少金币。
前置知识倍增https://oi-wiki.org/basic/binary-lifting/ 题目给出的是一个类似于内向基环树的图,根据对于每个i,a[Next[i]]跟a[i]关系可以建立一个边权图假设x,y都是正数,那么对于每次询问的最大前缀和都是走完即可,接下来就是处理负数对结局的影响.类似的我们可以利用倍增的思想额外去维护这个最大前缀和pre,前缀和就是sum,f(i,j)代表第i给点恰好走2j步,发现对于任意的区间l,r,f(l+r).sum=fl.sum+fr.sum 而最大前缀和有两种情况取max,从左边的序列 l 贡献 f(l+r).pre=max(f(l+r).pre,fl.pre)和从右边的序列r 贡献,因为必须是前缀需要加上左边序列的元素和 f(l+r).pre=max(fl.sum+fr.pre,f(l+r).pre) 接下来就可以在倍增数组上维护f(i,j)了
f(i+j).sum=f(i,j−1).sum+f(f(i,j−1),j−1).sum f(i+j).pre=max(f(i+j).pre,f(i,j−1).pre)